Android第一个绘制的Surface

语言: CN / TW / HK

如何监控冷启动

一旦系统创建了应用程序进程,应用程序进程就负责接下来的阶段:

  1. 创建应用程序对象。

  2. 启动主线程。

  3. 创建主要 Activity 。

  4. 填充 View 。

  5. 布置屏幕。

  6. 进行初始化绘制。

一旦应用进程完成了第一次绘制,系统进程就会换出当前显示的背景窗口,用主活动替换它。 此时,用户可以开始使用该应用程序。

主线程开始

在上一篇博文中,我们了解到:

当应用程序进程启动时,它会调用 ActivityThread.main(),它会在 system_server 进程中对 ActivityManagerService.attachApplication() 进行阻塞 IPC 调用。

system_server 进程对应用进程中的 ActivityThread.bindApplication() 进行 IPC 调用,这将 BIND_APPLICATION 消息排入主线程消息队列。

当对 ActivityManagerService.attachApplication() 的 IPC 调用完成后,ActivityThread.main() 然后调用 Looper.loop(),它会永远循环,处理发布到其 MessageQueue 的消息。

处理的第一条消息是 BIND_APPLICATION,它调用 ActivityThread.handleBindApplication() 来加载 APK 并加载应用程序组件。

这里重要的一点是,在对 ActivityManagerService.attachApplication() 的 IPC 调用返回之前,应用程序进程主线程中不会发生任何事情。

调度 Activity 启动

来看看调用ActivityThread.bindApplication()后system_server进程发生了什么: ``` public class ActivityManagerService extends IActivityManager.Stub {

private boolean attachApplicationLocked( IApplicationThread thread, int pid, int callingUid, long startSeq) { thread.bindApplication(...);

// See if the top visible activity is waiting to run
//  in this process...
mAtmInternal.attachApplication(...);

// Find any services that should be running in this process...
mServices.attachApplicationLocked(app, processName);

// Check if a next-broadcast receiver is in this process...
if (isPendingBroadcastProcessLocked(pid)) {
    sendPendingBroadcastsLocked(app);
}
return true;

} } ```

与 Activity 启动相关的行是 mAtmInternal.attachApplication(...)。 它调用 ActivityTaskManagerService.attachApplication() 调用 RootActivityContainer.attachApplication: ``` class RootActivityContainer extends ConfigurationContainer {

boolean attachApplication(WindowProcessController app) { for (ActivityDisplay display : mActivityDisplays) { ActivityStack stack = display.getFocusedStack() ActivityRecord top = stack.topRunningActivityLocked(); stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); for (ActivityRecord activity : mTmpActivityList) { if (activity.app == null && app.mUid == activity.info.applicationInfo.uid && app.mName.equals(activity.processName)) { mStackSupervisor.realStartActivityLocked( activity, app, top == activity / andResume /, true / checkConfig / ) } } } ... } } ```

上面的代码:

迭代每个 Display 。

检索该 Display 的焦点 Activity 堆栈。

迭代焦点 Activity 堆栈的每个 Activity 。

如果该 Activity 属于正在启动的进程,则调用 ActivityStackSupervisor.realStartActivityLocked()。 请注意,如果活动位于堆栈顶部,则传递为 true 的 andResume 参数。

这是 ActivityStackSupervisor.realStartActivityLocked(): ``` public class ActivityStackSupervisor{

boolean realStartActivityLocked( ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig ) { ... ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken);

clientTransaction.addCallback(LaunchActivityItem.obtain(...));

// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
    boolean forward = dc.isNextTransitionForward()
    lifecycleItem = ResumeActivityItem.obtain(forward);
} else {
    lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);

// Schedule transaction.
mService.getLifecycleManager()
  .scheduleTransaction(clientTransaction);
...

} } ```

到目前为止,我们看到的所有方法调用都发生在 system_server 进程中。 ClientLifecycleManager.scheduleTransaction() 在应用进程中对 ActivityThread.scheduleTransaction() 进行 IPC 调用,调用 ClientTransactionHandler.scheduleTransaction() 将 EXECUTE_TRANSACTION 消息放入主线程消息队列中: ``` public abstract class ClientTransactionHandler {

/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(
      ActivityThread.H.EXECUTE_TRANSACTION,
      transaction
    );
}

} ```

当 EXECUTE_TRANSACTION 被处理时,它调用 TransactionExecutor.execute()。

实际 Activity 启动

TransactionExecutor.execute() 调用 TransactionExecutor.performLifecycleSequence() 调用回 ActivityThread 来创建、启动和恢复活动: ``` public class TransactionExecutor {

private void performLifecycleSequence(...) { for (int i = 0, state; i < path.size(); i++) { state = path.get(i); switch (state) { case ON_CREATE: mTransactionHandler.handleLaunchActivity(...); break; case ON_START: mTransactionHandler.handleStartActivity(...); break; case ON_RESUME: mTransactionHandler.handleResumeActivity(...); break; case ON_PAUSE: mTransactionHandler.handlePauseActivity(...); break; case ON_STOP: mTransactionHandler.handleStopActivity(...); break; case ON_DESTROY: mTransactionHandler.handleDestroyActivity(...); break; case ON_RESTART: mTransactionHandler.performRestartActivity(...); break; } } } } ```

第一个绘制

让我们看看从 ActivityThread.handleResumeActivity() 导致第一次绘制的调用序列:

Choreographer.scheduleFrameLocked() 将 MSG_DO_FRAME 消息放入主线程消息队列中。

处理 MSG_DO_FRAME 时,它调用 Choreographer.doFrame(),后者调用 ViewRootImpl.doTraversal(),后者执行测量传递、布局传递,最后是视图层次结构上的第一个绘制传递(请参阅 Android 如何绘制视图)。