四大组建工作过程【1】根 Activity 启动过程

1,699 阅读8分钟

Activity 在启动流程上可以根据启动的处理逻辑不同分为两种: Root Activity 和普通的 Activity 。

Root Activity 是指 App 启动时创建的第一个 Activity 。因此,Root Activity 也可以理解为 App 的启动过程。

普通的 Activity 就是指除了 Root Activity 外的其他 Activity 。

两者的启动过程有重叠部分,所以这里以流程更全面的 Root Activity 为例介绍。

在 Android 系统启动完成后,创建了第一个系统应用程序 Launcher ,Launcher 会通过 PackageManager 去请求 PMS 加载 App 列表。App 的图标就是启动 Root Activity 的入口。 当我们在 Launcher 上点击一个 App 的图标后,就会通过请求 AMS 来启动这个 App。

Launcher 调用 ActivityManagerService

Launcher 请求 AMS 的调用栈如下:

- packages/apps/Launcher3/src/com/android/launcher3/Launcher.java#startActivitySafely
- packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.java#startActivitySafely

startActivitySafely

在这个方法中, Intent 设置 Flag 为 FLAG_ACTIVITY_NEW_TASK ,确保 Root Activity 在一个新的任务栈中启动。

然后继续查看调用栈:

- frameworks/base/core/java/android/app/Activity.java#startActivity
- frameworks/base/core/java/android/app/Activity.java#startActivityForResult
- frameworks/base/core/java/android/app/Instrumentation.java#execStartActivity

startActivityForResult

在这个方法中,会对 mParent 属性进行空检查,mParent 会在 Activity onAttach 时被赋值,代表当前启动的 Activity ,如果等于 null ,说明 Activity 没有创建完成。等于 null 时会继续调用 Instrumentation.execStartActivity ,否则调用:

mParent.startActivityFromChild(this, intent, requestCode, options);

execStartActivity

Instrumentation 的主要作用是用于监控应用程序和系统的交互。 内部最终调用 ActivityTaskManager 的 getService 方法来获取了一个 IActivityTaskManager 单例对象:

    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };

这个单例是通过 Binder 机制获取到的 。然后通过 IActivityTaskManager 远程调用ActivityTaskManangerService 的 startActivity 方法。

7CDE2A3C-41EB-4862-84FF-263E43F6E541.png

此时已经调用到了 ATMS 。

ATMS 到 ApplicationThread 的调用过程

- frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java#startActivity
- frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java#startActivityAsUser
- frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java#executeRequest

startActivityAsUser

46011D21-6201-4BB4-BDBC-B9AD4B5C593B.png

最终通过 ActivityStartController 对象的 obtainStarter 方法,获取一个 ActivityStarter 对象,然后通过链式调用传递参数,然后执行 execute 方法。 execute 方法,是在经过设置一些请求参数后调用,执行启动一个 Activity 请求:

伪代码逻辑:
- 构造一个 launchingState
- 加锁处理,获取 launchingState 的值
- 避免死锁处理
- 根据 intent,设置重启或关机检查点, 记录源 intent 信息和包名。
- 同步处理,获取执行请求的结果 关键方法 executeRequest(mRequest)

executeRequest

重点在 executeRequest 方法中。内部重点逻辑是:

- 检查权限
- 拦截器拦截调用行为
- 调用 startActivityUnchecked 方法

startActivityUnchecked :

image.png

这个方法是在完成大部分初步检查并确认调用者拥有必要的权限后,启动 Activity。这里还确保如果启动不成功,则删除启动的 Activity 。

在这个方法中,直接调用了 startActivityInner:

image.png

这个方法的备注是:

启动一个 Activity 并确定该 Activity 是否应该添加到现有任务栈顶部,或将新的 intent 传递给栈内已有的 Activity 。并将这个任务显示出来。

内部逻辑是:

- 计算并获取 Source Root Task
- 获取顶部的Task, 以防后续复用Task时,存在排序问题
- 调用 Task#startActivityLocked 
- mRootWindowContainer#resumeFocusedTasksTopActivities // 将 Activity 获取焦点,resume

Task

Task 是一个TaskFragment(继承自 TaskFragment ),可以包含一组 Activity 来执行某项工作。

TaskFragment 是一个基本容器,可容纳 Activity 或其他 TaskFragment,它还能够管理活动生命周期并更新其中活动的可见性。

同一任务关联的 Activity 通常分组在同一个任务中。一个 Task 也可以是一个入口,比如打开 Android 系统的最近任务列表,就会根据任务来出现多个窗口,注意这个列表同一个 App 可能会有多个任务窗口,比如小程序和微信是两个任务,在最近使用列表里会分别存在以一个窗口。

startActivityLocked 方法中,对 Task 或 ActivityRecord 对象进行处理,将其移动到显示区域。 然后是 resumeFocusedTasksTopActivities 方法,它的调用通过调用栈的形式来分析:

- frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java#resumeFocusedTasksTopActivities 
  RootWindowContainer 是 WindowContainer 的子类,代表根窗口容器。
- frameworks/base/services/core/java/com/android/server/wm/Task.java#resumeTopActivityUncheckedLocked

resumeTopActivityUncheckedLocked

Task 代表当前 Activity 任务栈,保存启动 Activity 的一些相关信息。在 Android 中,系统维护了所有应用的状态信息。它也是 WindowContainer 的子类,用于管理和表示同一栈帧中的所有 Activity ,Activity 用 ActivityRecord 表示。

这个方法将当前 Task 顶部的 Activity 进行 Resume。直接调用此方法是不安全的,因为它可能导致无焦点的任务栈中的 Activity 进行 Resume。

这个方法是个递归:

- 是叶子任务,执行 resumeTopActivityInnerLocked 方法,
- 否则遍历 children Task 检查是否有焦点 isTopActivityFocusable
  - 有焦点,检查是否展示,调用子任务的resumeTopActivityUncheckedLocked 递归检查子任务的子任务。

resumeTopActivityInnerLocked

- 通过topRunningActivity方法获取一个ActivityRecord对象
- 通过 ActivityRecord#getTaskFragment 获取TaskFragment
- 遍历所有的叶子 TaskFragment 执行
  - 若可以变为 Resumed,调用TaskFragment#resumeTopActivity
- 最终返回TaskFragment#resumeTopActivity的结果

TaskFragment 是 可用于包含 Activity 或其他 TaskFragment 的基本容器,它还能够管理 Activity 生命周期并更新其中 Activity 的可见性。

resumeTopActivity

在这个方法中,最后执行了关键代码:

E83F0914-9AD8-4A72-A25E-DDF75D62D9A6.png

内部执行到了 ActivityTaskSupervisor#startSpecificActivity 方法。

startSpecificActivity

255BE7D1-9C6A-4B27-BFCC-5B19851652EB.png

在这个方法中,主要通过 WindowProcessController 和它是否存在线程来判断了目标 Activity 所在的应用是否在运行,如果在运行就直接通过 realStartActivityLocked 启动 Activity,否则就通过 ActivityTaskManagerService#startProcessAsync 去异步启动一个新进程。

  • 进程存在的情况:ActivityTaskSupervisor#realStartActivityLocked
      - 给 ActivityRecord 设置进程
      - LockTaskController#startLockTaskMode
      - 创建 activity 启动 Transaction,同时获取 lifecycleItem (生命周期)
      - 执行 Transaction
    

该函数的核心作用是创建 Transaction 并分发给生命周期管理器处理。

885461E3-1622-40D0-A173-BAF945C635C9.png

这里的 ActivityLifecycleItem 是生命周期:

final ActivityLifecycleItem lifecycleItem;
if (andResume) {
    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
    lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);

在文章结尾会介绍 ActivityLifecycleItem ,这里需要注意一下,生命周期是从这里开始的。

ClientTransaction

ClientTransaction 是包含一系列消息的容器,这些消息可以发送到客户端。这包括 callbacks 和最终的生命周期状态。

setLifecycleStateRequest 方法用于设置客户端在执行事务后应该处于的生命周期状态。参数类型是 ActivityLifecycleItem 。 在这个类型中定义了生命周期对应的枚举常量,如 ON_CREATE 。

这里的 mService 是 ATMS ,getLifecycleManager 返回的是 ClientLifecycleManager。

ClientLifecycleManager#scheduleTransaction

0B6B0D89-843E-46F4-BDAC-3ECFE370E837.png

这个方法最终是调用了 ClientTransaction 自己的 schedule 方法。

AB5E31CE-635C-41A8-8321-6E18BB1CAAAD.png

而这里的 mClient 是 IApplicationThread 类型,其 AIDL 定义在 frameworks/base/core/java/android/app/IApplicationThread.aidl 文件中,最终会调用到应用程序所在的客户端,客户端的实现类为 ActivityThread 的内部类 ApplicationThread 的 scheduleTransaction 方法:

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

这个方法里面调用到的是 ClientTransactionHandler 的 scheduleTransaction 方法:

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

最后发送了一个 Handler 消息 EXECUTE_TRANSACTION

而 ClientTransactionHandler 是一个抽象类, ActivityThread 继承自 ClientTransactionHandler 。 实际上, Transaction 通过 Binder 机制,从 SystemServer 进程中,传递给应用程序进程中的 ActivityThread 中的 ApplicationThread,然后 ApplicationThread 调用 ActivityThread#sendMessage 方法,发送不同的消息出去。也是这个时候,事件由内部类 ApplicationThread ,传递给 ActivityThread

AFDFC4D4-2DF4-4018-A1D8-58B6CFB68DA5.png

sendMessage 方法中通过 mH 对象发送消息,这个 mH 是一个 Handler ,类型是 H :

97C9B1DF-A96A-4B3D-B5E9-DA7B8D2A05AA.png

到此时开始,ActivityThread 中就通过 Handler 机制去处理消息了。 H 是应用程序进程中,主线程的消息管理类,因为 ApplicationThread 是一个 Binder,所以它的调用逻辑在 Binder 线程池中,所以这里需要通过 H 将代码的逻辑切换到主线程。

H 中,执行 EXECUTE_TRANSACTION 的 case 是:

case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        // Client transactions inside system process are recycled on the client side
        // instead of ClientLifecycleManager to avoid being cleared before this
        // message is handled.
        transaction.recycle();
    }
    // TODO(lifecycler): Recycle locally scheduled transactions.
    break;

通过一个 TransactionExecutor 执行器来执行 ClientTransaction :

    public void execute(ClientTransaction transaction) {
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");

        final IBinder token = transaction.getActivityToken();
        if (token != null) {
            final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
                    mTransactionHandler.getActivitiesToBeDestroyed();
            final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
            if (destroyItem != null) {
                if (transaction.getLifecycleStateRequest() == destroyItem) {
                    activitiesToBeDestroyed.remove(token);
                }
                if (mTransactionHandler.getActivityClient(token) == null) {
                    // 该 Activity 尚未创建但已被请求销毁
                    Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
                            + transactionToString(transaction, mTransactionHandler));
                    return;
                }
            }
        }

        if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }

从代码中看,关键方法是最后执行的 executeCallbacks 方法和 executeLifecycleState 方法: executeCallbacks:

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null || callbacks.isEmpty()) {
            // No callbacks to execute, return early.
            return;
        }
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");

        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        // In case when post-execution state of the last callback matches the final state requested
        // for the activity in this transaction, we won't do the last transition here and do it when
        // moving to final state instead (because it may contain additional parameters from server).
        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
        // Index of the last callback that requests some post-execution state.
        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState, transaction);
            }

            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            if (r == null) {
                // Launch activity request will create an activity record.
                r = mTransactionHandler.getActivityClient(token);
            }

            if (postExecutionState != UNDEFINED && r != null) {
                // Skip the very last transition and perform it by explicit state request instead.
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

executeLifecycleState:

    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }

        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
                    + lifecycleItem + " for activity: "
                    + getShortActivityName(token, mTransactionHandler));
        }

        if (r == null) {
            // Ignore requests for non-existent client records for now.
            return;
        }

        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

两者逻辑大致相同, executeLifecycleState 最终是调用 ActivityLifecycleItem 的 execute 和 postExecute 方法;executeCallbacks 最终调用的是 ClientTransactionItem 的 execute 和 postExecute 方法。 ActivityLifecycleItem 继承自 ActivityTransactionItem , 而 ActivityTransactionItem 继承自 ClientTransactionItem。

ActivityLifecycleItem

ActivityLifecycleItem 中,定义了生命周期相关的字段:

    public @interface LifecycleState{}
    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;
    public static final int ON_RESTART = 7;

它自己也是个抽象类,它的实现类就是我们常见的生命周期:

20AB91C8-03B4-4A93-82E9-ACE238BBAEB3.png

它们都执行了传入的 mTransactionHandler ( ClientTransactionHandler ) 的方法。也就是执行了它的实现类 ActivityThread 中对应的方法。 在 ActivityTaskSupervisor.realStartActivityLocked 方法中,最后调用了 ClientTransaction.setLifecycleStateRequest方法,这个方法需要一个 ActivityLifecycleItem 类型参数,用来处理生命周期的状态切换。

ActivityTransactionItem 的 execute 方法最终调用到了 getActivityClientRecord 方法:

    @NonNull ActivityClientRecord getActivityClientRecord(
            @NonNull ClientTransactionHandler client, IBinder token, boolean includeLaunching) {
        ActivityClientRecord r = null;
        // Check launching Activity first to prevent race condition that activity instance has not
        // yet set to ActivityClientRecord.
        if (includeLaunching) {
            r = client.getLaunchingActivity(token);
        }
        // Then if we don't want to find launching Activity or the ActivityClientRecord doesn't
        // exist in launching Activity list. The ActivityClientRecord should have been initialized
        // and put in the Activity list.
        if (r == null) {
            r = client.getActivityClient(token);
            if (r != null && client.getActivity(token) == null) {
                throw new IllegalArgumentException("Activity must not be null to execute "
                        + "transaction item");
            }
        }
        if (r == null) {
            throw new IllegalArgumentException("Activity client record must not be null to execute "
                    + "transaction item");
        }
        return r;
    }

最终实际上根据 token 获取了一个 ActivityClientRecord 对象。这些对象存储在 ActivityThread 的 mActivities 中:

final ArrayMap<IBinder, ActivityClientRecord>  mActivities = new ArrayMap<>();

这样,在执行生命周期切换时,也会更新对应的 ActivityClientRecord 。

而 preExecute 在 ClientTransaction 方法中定义,内部循环调用了 callback 和 ActivityLifecycleItem 的 preExecute 方法:

    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i < size; ++i) {
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }

preExecute 方法的定义在 接口 BaseClientRequest 中,它的抽象子类是 ClientTransactionItem 。默认空实现。

总结

整体来说 Activity 的启动涉及两个流程。

  1. Launcher 通过 Binder 机制调用 ActivityTaskManangerService 的 startActivity 方法。
  2. ATMS 通过 ActivityStarter ,创建 Task 。然后通过调用 Task ,创建 Activity 和 Transaction,同时处理生命周期。
  • 执行 Transaction,通过 Binder 机制 ATMS 调用到 ActivityThread 的内部类ApplicationThread。
  • ApplicationThread 调用 ClientTransactionHandler ,ClientTransactionHandler 的实现类是 ActivityThread ,所以这里通过 Handler 机制切换到主线程 ActivityThread 的 EXECUTE_TRANSACTION 消息。
  • EXECUTE_TRANSACTION 是用来处理生命周期的,所以 ApplicationThread 调用到 ActivityThread ,主要是为了处理生命周期切换逻辑。

以上就是 Activity 启动的全过程。