阅读 206

Android第一个绘制的Surface

如何监控冷启动

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

  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 如何绘制视图)。

文章分类
Android
文章标签