startActivity 启动过程分析

时间:2021-7-3 作者:qvyue

整个 startActivity 的流程分为 3 大部分,也涉及 3 个进程之间的交互:

startActivity 启动过程分析
image.png
1. ActivityA --> ActivityManagerService(简称 AMS)
2. ActivityManagerService --> ApplicationThread
3. ApplicationThread --> Activity

1.ActivityA –> ActivityManagerService 阶段

startActivity 启动过程分析
ActivityA –> ActivityManagerService 阶段

Activity 的 startActivity

startActivity 启动过程分析
Activity 的 startActivity

最终调用到了startActivityForResult,传入-1表示不需要获取startActivity的结果。

Activity 的 startActivityForResult

startActivity 启动过程分析
Activity 的 startActivityForResult

1.Instrumentation 类主要用来监控应用程序与系统交互。
2.mMainThread是ActivityThread,可以理解为一个进程,初始启动Activity所在的进程。
3.通过 mMainThread 获取一个 ApplicationThread 的引用,这个引用就是用来实现进程间通信的,具体来说就是 AMS 所在系统进程通知应用程序进程进行的一系列操作。

Instrumentation 的 execStartActivity

startActivity 启动过程分析
Instrumentation 的 execStartActivity

在 Instrumentation.execStartA ctivity方法中,先通过 ActivityManger.getService 获取 AMS 的实例,然后调用其 startActivity 方法,实际上这里就是通过 AIDL 来调用 AMS 的 startActivity 方法,至此,startActivity 的工作重心成功地从进程 A 转移到了系统进程 AMS 中。

2.ActivityManagerService –> ApplicationThread

AMS–>ApplicationThread 流程里面实际做了两件事:
1.综合处理 launchMode 和 Intent 中的 Flag 标志位,并根据处理结果生成一个目标 Activity B 的对象(ActivityRecord)。
2.判断是否需要为目标 Activity B 创建一个新的进程(ProcessRecord)、新的任务栈(TaskRecord)。

AMS 的 startActivity

startActivity 启动过程分析
AMS 的 startActivity

经过多次调用,最终调用到startActivityAsUser方法中,通过obtainStarter方法获取ActivityStarter 类型的对象,然后调用其 execute 方法。在 execute 方法中,会再次调用其内部的 startActivityMayWait 方法。

ActivityStarter 的 startActivityMayWait

startActivity 启动过程分析
ActivityStarter 的 startActivityMayWait

1.通过ActivityStackSupervisor获取ResolveInfo信息。resolveIntent 中实际上是调用系统PackageManagerService 来获取最佳 Activity。
有时候我们通过隐式 Intent 启动 Activity 时,系统中可能存在多个 Activity 可以处理 Intent,此时会弹出一个选择框让用户选择具体需要打开哪一个 Activity 界面,就是此处的逻辑处理结果。
2.通过ActivityStackSupervisor获取ActivityInfo信息。
3.调用重载方法startActivity启动Activity。

从图中可以看出获取目标 Activity 信息的操作由 mSupervisor 来实现,它是 ActivityStackSupervisor 类型,从名字也能猜出它主要是负责 Activity 所处栈的管理类。

startActivity 方法,而最终会调用的 ActivityStarter 中的 startActivityUnchecked 方法来获取启动 Activity 的结果。

ActivityStarter 的 startActivityUnchecked

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
...
//计算启动 Activity 的 Flag 值
 computeLaunchingTaskFlags();
...
//处理 Task 和 Activity 的进栈操作
  mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,mOptions);
...
//启动栈中顶部的 Activity
 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);
...
}

computeLaunchingTaskFlags方法如下:

startActivity 启动过程分析
image.png

这个计算启动Activity的Flag值,不同的 Flag 决定了启动 Activity 最终会被放置到哪一个 Task 集合中。

  1. mInTask 是 TaskRecord 类型,此处为 null,代表 Activity 要加入的栈不存在,因此需要判断是否需要新建 Task。
  2. mSourceRecord 的类型 ActivityRecord 类型,它是用来描述“初始 Activity”, ActivityA 启动了ActivityB,ActivityA 就是初始 Activity。当我们使用 Context 或者 Application 启动 Activity 时, SourceRecord 为 null。
  3. 表示初始 Activity 如果是在 SingleInstance 栈中的 Activity,这种需要添加 NEW_TASK 的标识。SingleInstance 栈只能允许保存一个 Activity。
  4. 如果 Launch Mode 设置了 singleTask 或 singleInstance,则也要创建一个新栈。

ActivityStack 的 startActivityLocked

startActivity 启动过程分析
ActivityStack 的 startActivityLocked

调用 insertTaskAtTop 方法尝试将 Task 和 Activity 入栈。如果 Activity 是以 newTask 的模式启动或者 TASK 堆栈中不存在该 Task id,则 Task 会重新入栈,并且放在栈的顶部。需要注意的是:Task 先入栈,之后才是 Activity 入栈,它们是包含关系。

startActivity 启动过程分析
image.png

一个ActivityRecord对应一个Activity,保存了一个Activity的所有信息; 但是一个Activity可能会有多个ActivityRecord,因为Activity可以被多次启动,这个主要取决于其启动模式。

一个TaskRecord由一个或者多个ActivityRecord组成,这就是我们常说的任务栈,具有后进先出的特点。

ActivityStack则是用来管理TaskRecord的,包含了多个TaskRecord。
参考Activity启动流程

ActivityStackSupervisor的resumeFocusedStackTopActivityLocked

startActivity 启动过程分析
image.png

startActivity 启动过程分析
image.png
startActivity 启动过程分析
image.png

经过一系列调用,最终代码有回到了ActivityStackSupervisor 中的 startSpecificActivityLocked 方法。

ActivityStackSupervisor 的 startSpecificActivityLocked

startActivity 启动过程分析
image.png

1.根据进程名称和 Application 的 uid 来判断目标进程是否已经创建,如果没有则代表进程未创建。
2.不管是目标进程已经存在还是新建目标进程,最终都会调用图中红线标记的 realStartActivityLocked 方法来执行启动 Activity 的操作。
3.调用 AMS 创建 Activity 所在进程。

ActivityStackSupervisor 的 realStartActivityLocked

startActivity 启动过程分析
image.png
  1. 处创建 Activity 启动事务,并传入 app.thread 参数,它是 ApplicationThread 类型。在上文 startActivity 阶段已经提过 ApplicationThread 是为了实现进程间通信的,是 ActivityThread 的一个内部类。
  2. 处执行 Activity 启动事务。

Activity 启动事务的执行是由 ClientLifecycleManager 来完成的。
ClientLifecycleManager.scheduleTransaction

startActivity 启动过程分析
image.png

可以看出实际上是调用了启动事务 ClientTransaction 的 schedule 方法,而这个 transaction 实际上是在创建 ClientTransaction 时传入的 app.thread 对象,也就是 ApplicationThread。

startActivity 启动过程分析
image.png
startActivity 启动过程分析
image.png
  1. 传入的 app.thread 会赋值给 ClientTransaction 的成员变量 mClient,ClientTransaction 会调用 mClient.scheduleTransaction(this) 来执行事务。
  2. app.thread 是 ActivityThread 的内部类 ApplicationThread,所以事务最终是调用 app.thread 的 scheduleTransaction 执行。
  3. 到这为止 startActivity 操作就成功地从 AMS 转移到了另一个进程 B 中的 **ApplicationThread **中,剩下的就是 AMS 通过进程间通信机制通知 ApplicationThread 执行 ActivityB 的生命周期方法。

3.ApplicationThread -> Activity

刚才我们已近分析了 AMS 将启动 Activity 的任务作为一个事务 ClientTransaction 去完成,在 ClientLifecycleManager 中会调用 ClientTransaction的schedule() 方法,如下:

startActivity 启动过程分析
image.png

mClient 是一个 IApplicationThread 接口类型,具体实现是 ActivityThread 的内部类 ApplicationThread。因此后续执行 Activity 生命周期的过程都是由 ApplicationThread 指导完成的,scheduleTransaction 方法如下:

startActivity 启动过程分析
image.png

调用了ActivityThread 的 scheduleTransaction 方法。但是这个方法实际上是在 ActivityThread 的父类 ClientTransactionHandler 中实现,具体如下:

startActivity 启动过程分析
image.png

调用 sendMessage 方法,向 Handler 中发送了一个 EXECUTE_TRANSACTION 的消息,并且 Message 中的 obj 就是启动 Activity 的事务对象。而这个 Handler 的具体实现是 ActivityThread 中的 mH 对象。具体如下:

public final class ActivityThread extends ClientTransactionHandler {
      final H mH = new H();
      class H extends Handler {
            ...
               case EXECUTE_TRANSACTION:
                        return "EXECUTE_TRANSACTION";
            ...

             public void handleMessage(Message msg) {
                    case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    ...
            }  
    }
}

最终调用了事务的 execute 方法,execute 方法如下:

public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }

public void executeCallbacks(ClientTransaction transaction) {
    final int size = callbacks.size();
        for (int i = 0; i 

在 executeCallback 方法中,会遍历事务中的 callback 并执行 execute 方法,这些 callbacks 是何时被添加的呢?

startActivity 启动过程分析
image.png

在创建 ClientTransaction 时,通过 addCallback 方法传入了 Callback 参数,从图中可以看出其实是一个 LauncherActivityItem 类型的对象。

LaunchActivityItem 的 execute()

startActivity 启动过程分析
image.png

终于到了跟 Activity 生命周期相关的方法了,图中 client 是 ClientTransationHandler 类型,实际实现类就是 ActivityThread。因此最终方法又回到了 ActivityThread。

ActivityThread 的 handleLaunchActivity
Activity 的生命周期方法就是在这个方法中有序执行,具体如下:

 public Activity handleLaunchActivity(ActivityClientRecord r,
                                         PendingTransactionActions pendingActions, Intent customIntent) {
       //1
       WindowManagerGlobal.initialize();     
        //2
      final Activity a = performLaunchActivity(r, customIntent);    
    ...
}
 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
     try {
            //3
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
        ...
      }
      ...
            //4
           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, r.configCallback);
        ...
            //5
          if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
}
  1. 初始化 Activity 的 WindowManager,每一个 Activity 都会对应一个“窗口。
  2. 调用 performLaunchActivity 创建并显示 Activity。
  3. 通过反射创建目标 Activity 对象。
  4. 调用 attach 方法建立 Activity 与 Context 之间的联系,创建 PhoneWindow 对象,并与 Activity 进行关联操作。
  5. 通过 Instrumentation 最终调用 Activity 的 onCreate 方法。

4.总结

Activity 的启动过程主要涉及 3 个进程间的通信过程:
首先进程 A 通过 Binder 调用 AMS 的 startActivity 方法。
然后 AMS 通过一系列的计算构造目标 Intent,然后在 ActivityStack 与 ActivityStackSupervisor 中处理 Task 和 Activity 的入栈操作。
最后 AMS 通过 Binder 机制,调用目标进程中 ApplicationThread 的方法来创建并执行 Activity 生命周期方法,实际上 ApplicationThread 是 ActivityThread 的一个内部类,它的执行最终都调用到了 ActivityThread 中的相应方法。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。