美文网首页Android开发Android开发经验谈Android技术知识
开发12年Android,整理这个居然让怀疑我是不是做了个假An

开发12年Android,整理这个居然让怀疑我是不是做了个假An

作者: jett老师 | 来源:发表于2020-06-29 10:25 被阅读0次

    前言

    应用启动流程简单分为三个模块,其中最后由ActivityThread启动Activity是常见的面试高频问题,所以前面两个部分简单整理(有空再上源码分析),第三部分从源码分析,讲的比较详细。

    一.Launcher请求ActivityManageService

    1.点击图标,调用 launcher类 的 startActivitySafely 方法,其中调用了内部方法 startActivity,
    2.方法里设置了 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);这样根Activity会在新的任务栈中启动,然后调用了activity的 startActivity方法
    3.startActivity 又调用 startActivityForResult 方法
    4.startActivityForResult 中判断mParent 是否为空 ,因为是根Activity还没创建,所以会走为空的分支 ,调用 Instrumentation的 execStartActivity 方法(不为空 走startActivityFromChild 方法 这个方法最终还是调用 Instrumentation的 execStartActivity 方法 具体情况后续分析)
    5.看到 nstrumentation的 execStartActivity 方法 ,首先会调用ActivityManagerNative的getDefault来获取ActivityManageService(以后简称为AMS)的代理对象(AMP),接着调用它的startActivity方法。
    6.AMP是 ActivityManagerNative 的内部类 ,startActivity方法,通过IBinder对象mRemote向AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用ActivityManagerNative的onTransact方法中执行,
    7.onTransact中会调用AMS的startActivity方法


    二.ActivityManageService到ApplicationThread的调用流程

    1.AMS的startActivity方法中return了startActivityAsUser方法:
    2.startActivityAsUser方法中又return了mActivityStarter的startActivityMayWait方法
    3.又调用了startActivityLocked方法
    4.接着又调用startActivityUnchecked方法:
    5.startActivityUnchecked方法中调用了ActivityStackSupervisor类型的mSupervisor的resumeFocusedStackTopActivityLocked方法
    6.在注释1处又调用了ActivityStack类型mFocusedStack的resumeTopActivityUncheckedLocked方法:
    7.紧接着查看ActivityStack的resumeTopActivityInnerLocked方法
    8.最后运行 realStartActivityLocked方法 ,app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。最后调用了ApplicationThread的scheduleLaunchActivity方法

    三.ActivityThread启动Activity(重点来了)

    ApplicationThread的scheduleLaunchActivity方法,scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecord,调用sendMessage传递参数

    frameworks/base/core/java/android/app/ActivityThread.java:

    @Override
    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
            CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
     updateProcessState(procState, false);
        ActivityClientRecord r = new ActivityClientRecord();
        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.referrer = referrer;
        r.voiceInteractor = voiceInteractor;
        r.activityInfo = info;
        r.compatInfo = compatInfo;
        r.state = state;
        r.persistentState = persistentState;
        r.pendingResults = pendingResults;
        r.pendingIntents = pendingNewIntents;
        r.startsNotResumed = notResumed;
        r.isForward = isForward;
        r.profilerInfo = profilerInfo;
        r.overrideConfig = overrideConfig;
        updatePendingConfiguration(curConfig);
        sendMessage(H.LAUNCH_ACTIVITY, r);//传递参数
    }
    

    sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去,

    frameworks/base/core/java/android/app/ActivityThread.java:

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
       ...
          mH.sendMessage(msg);
      }
    

    这里mH指的是H,它是ActivityThread的内部类并继承Handler,H的代码如下所示。
    frameworks/base/core/java/android/app/ActivityThread.java

    private class H extends Handler {
          public static final int LAUNCH_ACTIVITY         = 100;
          public static final int PAUSE_ACTIVITY          = 101;
    ...
    public void handleMessage(Message msg) {
              if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
              switch (msg.what) {
                  case LAUNCH_ACTIVITY: {
                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                      final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1
                      r.packageInfo = getPackageInfoNoCheck(
                              r.activityInfo.applicationInfo, r.compatInfo);//2
                      handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3
                      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                  } break;
                  case RELAUNCH_ACTIVITY: {
                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                      ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                      handleRelaunchActivity(r);
                      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                  } break;
                ...
    

    查看H的handleMessage方法中对LAUNCH_ACTIVITY的处理,在注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。
    在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord 的成员变量packageInfo 。应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件。
    在注释3处调用handleLaunchActivity方法,代码如下所示。

    frameworks/base/core/java/android/app/ActivityThread.java

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...
          Activity a = performLaunchActivity(r, customIntent);//1
          if (a != null) {
              r.createdConfig = new Configuration(mConfiguration);
              reportSizeConfigurations(r);
              Bundle oldState = r.state;
              handleResumeActivity(r.token, false, r.isForward,
                      !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//2
    
              if (!r.activity.mFinished && r.startsNotResumed) {      
                  performPauseActivityIfNeeded(r, reason);
                  if (r.isPreHoneycomb()) {
                      r.state = oldState;
                  }
              }
          } else {
              try {
                  ActivityManagerNative.getDefault()
                      .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                              Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
              } catch (RemoteException ex) {
                  throw ex.rethrowFromSystemServer();
              }
          }
      }
    

    注释1处的performLaunchActivity方法用来启动Activity ,注释2处的代码用来将Activity 的状态置为Resume。如果该Activity为null则会通知ActivityManager停止启动Activity。来查看performLaunchActivity方法做了什么:

    frameworks/base/core/java/android/app/ActivityThread.java

      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
      ...
            ActivityInfo aInfo = r.activityInfo;//1获取ActivityInfo
            if (r.packageInfo == null) {
                r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                        Context.CONTEXT_INCLUDE_CODE);//2获取APK文件的描述类LoadedApk
            }
            ComponentName component = r.intent.getComponent();//3获取要启动的Activity的ComponentName类
          ...
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);//4用类加载器来创建该Activity的实例
               ...
                }
            } catch (Exception e) {
             ...
            }
            try {
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);//5创建Application
    
            ...
                if (activity != null) {
                    Context appContext = createBaseContextForActivity(r, activity);//6创建要启动Activity的上下文环境
             ...
                    }
                    /**
                    *7用Activity的attach方法初始化Activity
                    */
                    activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window);
    
                  ...
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8调用Instrumentation的callActivityOnCreate方法来启动Activity
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
                    ...
            }
            return activity;
    }
    

    注释1处用来获取ActivityInfo,在注释2处获取APK文件的描述类LoadedApk。注释3处获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。注释4处根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。注释5处用来创建Application,makeApplication方法内部会调用Application的onCreate方法。注释6处用来创建要启动Activity的上下文环境。注释7处调用Activity的attach方法初始化Activity,attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。注释8处会调用Instrumentation的callActivityOnCreate方法来启动Activity:

    frameworks/base/core/java/android/app/Instrumentation.java

    public void callActivityOnCreate(Activity activity, Bundle icicle,
             PersistableBundle persistentState) {
         prePerformCreate(activity);
         activity.performCreate(icicle, persistentState);//1
         postPerformCreate(activity);
     }
    

    注释1处调用了Activity的performCreate方法,代码如下所示。

    frameworks/base/core/java/android/app/Activity.java

    final void performCreate(Bundle icicle) {
          restoreHasCurrentPermissionRequest(icicle);
          onCreate(icicle);
          mActivityTransitionState.readState(icicle);
          performCreateCommon();
      }
    

    performCreate方法中会调用Activity的onCreate方法,这样Activity就启动了,即应用程序就启动了。


    有想学习Android的程序员,或者是想进阶提升的成为Android高级架构师的程序员都可以点击【Android高级工程师进阶学习】加入我们的圈子领取资料和我们一起吧学习交流!下面是我在开发12年以来,整理搜集的一些资料,不多但是好在比较系统有需要的朋友,可以自行领取!
    • Android进阶学习全套手册
      关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。
    • Android高级架构师进阶知识体系图
      关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!

    • Android对标阿里P7学习视频

    • BATJ大厂Android高频面试题
      这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

    相关文章

      网友评论

        本文标题:开发12年Android,整理这个居然让怀疑我是不是做了个假An

        本文链接:https://www.haomeiwen.com/subject/ratofktx.html