美文网首页
Activity启动流程分析

Activity启动流程分析

作者: 就叫汉堡吧 | 来源:发表于2022-12-21 10:03 被阅读0次
    • 概述

      本文分析Activity在FrameWork层的启动流程,基于API29源码进行分析。

      不管是在Launcher启动还是程序内自写代码的启动,最终都是通过startActivity方法开启Activty启动流程,startActivity方法又有通过ContextImpl和Activity两种方式实现,前者是通过ActivityThread的Instrumentation实现,后者是通过Activity的Instrumentation实现,其实都是同一个Instrumentation,只不过这个Instrumentation实例是在Activity的启动过程中创建的,如果我们要找一个开始,那就是系统启动Launcher的时候会创建一个Instrumentation,而一切都是从它的execStartActivity方法开始的。

    • Instrumentation的execStartActivity方法

      Instrumentation的意思是仪表盘,意味着它是启动的外在控制接口。

      public ActivityResult execStartActivity(
              Context who, IBinder contextThread, IBinder token, Activity target,
              Intent intent, int requestCode, Bundle options) {
          IApplicationThread whoThread = (IApplicationThread) contextThread;
            ...
          try {
              ...
              int result = ActivityTaskManager.getService()
                  .startActivity(whoThread, who.getBasePackageName(), intent,
                          intent.resolveTypeIfNeeded(who.getContentResolver()),
                          token, target != null ? target.mEmbeddedID : null,
                          requestCode, 0, null, options);
                //启动结果会以int的形式返回,这里检查各种异常
              checkStartActivityResult(result, intent);
          } catch (RemoteException e) {
              throw new RuntimeException("Failure from system", e);
          }
          return null;
      }
      

      这里调用了ActivityTaskManager.getService():

      public static IActivityTaskManager getService() {
          return IActivityTaskManagerSingleton.get();
      }
      
      @UnsupportedAppUsage(trackingBug = 129726065)
      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类型实例,它的实现类是ActivityTaskManagerService。

    • ActivityTaskManagerService的startActivityAsUser方法

      int startActivityAsUser(IApplicationThread caller, String callingPackage,
              Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
              int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
              boolean validateIncomingUser) {
          enforceNotIsolatedCaller("startActivityAsUser");
      
          userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                  Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
      
          // TODO: Switch to user app stacks here.
          return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                  .setCaller(caller)
                  .setCallingPackage(callingPackage)
                  .setResolvedType(resolvedType)
                  .setResultTo(resultTo)
                  .setResultWho(resultWho)
                  .setRequestCode(requestCode)
                  .setStartFlags(startFlags)
                  .setProfilerInfo(profilerInfo)
                  .setActivityOptions(bOptions)
                  .setMayWait(userId)
                  .execute();
      
      }
      

      startActivity最终会调用到startActivityAsUser方法,getActivityStartController方法获取一个ActivityStartController对象,它在ActivityTaskManagerService初始化(initialize方法)的时候创建,它的obtainStarter方法如下:

      ActivityStarter obtainStarter(Intent intent, String reason) {
          return mFactory.obtain().setIntent(intent).setReason(reason);
      }
      

      这个mFactory是在构造时传入的ActivityStarter.DefaultFactory:

      @Override
      public ActivityStarter obtain() {
          ActivityStarter starter = mStarterPool.acquire();
      
          if (starter == null) {
              starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
          }
      
          return starter;
      }
      

      可见obtainStarter返回的就是ActivityStarter。

    • ActivityStarter

      ActivityStarter对象进行的一系列的set调用把信息都封装到了一个ActivityStarter.Request对象中,然后调用execute方法:

      int execute() {
          try {
              // TODO(b/64750076): Look into passing request directly to these methods to allow
              // for transactional diffs and preprocessing.
              if (mRequest.mayWait) {
                  return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                          mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                          mRequest.intent, mRequest.resolvedType,
                          mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                          mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                          mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                          mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                          mRequest.inTask, mRequest.reason,
                          mRequest.allowPendingRemoteAnimationRegistryLookup,
                          mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
              } else {
                  return startActivity(mRequest.caller, ...);
              }
          } finally {
              onExecutionComplete();
          }
      }
      

      因为调用了setMayWait方法,这个方法里会设置mRequest.mayWait为true,表示是否等待Activity的启动结果,因此这里会走到startActivityMayWait方法,其内部又调用了:

      int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
              voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
              callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
              ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
              allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
              allowBackgroundActivityStart);
      

      startActivity方法有一系列重载,在最后一个startActivity中:

      private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                  IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                  int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                  ActivityRecord[] outActivity, boolean restrictedBgActivity) {
          int result = START_CANCELED;
          final ActivityStack startedActivityStack;
          try {
              mService.mWindowManager.deferSurfaceLayout();
              result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                      startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
          } finally {
                ...
              if (ActivityManager.isStartResultSuccessful(result)) {
                  if (startedActivityStack != null) {
                      // we have to update the configuration for changing to different display.
                      final ActivityRecord currentTop =
                              startedActivityStack.topRunningActivityLocked();
                      if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
                          mRootActivityContainer.ensureVisibilityAndConfig(
                                  currentTop, currentTop.getDisplayId(),
                                  true /* markFrozenIfConfigChanged */, false /* deferResume */);
                      }
                  }
              } else{...}
              mService.mWindowManager.continueSurfaceLayout();
          }
          postStartActivityProcessing(r, result, startedActivityStack);
          return result;
      }
      

      可以看到,这里调用了startActivityUnchecked方法继续启动:

      //创建或者获取要启动的Activity所附属的ActivityTask
      if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
              && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
          newTask = true;
          result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
      } else if (mSourceRecord != null) {
          result = setTaskFromSourceRecord();
      } else if (mInTask != null) {
          result = setTaskFromInTask();
      } else {
          result = setTaskToCurrentTopOrCreateNewTask();
      }
      
      if (mDoResume) {
          if (!mTargetStack.isFocusable()
                  || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                  && mStartActivity != topTaskActivity)) {
              if (mTargetStack.isFocusable()
                      && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                  mTargetStack.moveToFront("startActivityUnchecked");
              }
              mRootActivityContainer.resumeFocusedStacksTopActivities(
                      mTargetStack, mStartActivity, mOptions);
          }
      } 
      

      mDoResume在前面startActivity方法入口时传入的是true,mTargetStack是前面获取的要启动的Activity所属的Task,如果不在前台则调用moveToFront方法将其移到前台,然后调用mRootActivityContainer的resumeFocusedStacksTopActivities方法:

      boolean resumeFocusedStacksTopActivities(
              ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
            ...
          boolean result = false;
          if (targetStack != null && (targetStack.isTopStackOnDisplay()
                  || getTopDisplayFocusedStack() == targetStack)) {
              result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
          }
            ...
      }
      

      resumeTopActivityUncheckedLocked方法如下:

      boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            ...
          boolean result = false;
          try {
              // Protect against recursion.
              mInResumeTopActivity = true;
              result = resumeTopActivityInnerLocked(prev, options);
                ...
          }...
          return result;
      }
      

      这里又调用了resumeTopActivityInnerLocked方法:

      private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
            ...
            ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
            ...
          if (next.attachedToProcess()) {
                ...
          }else{
                ...
              mStackSupervisor.startSpecificActivityLocked(next, true, true);
          }
            return true;
      }
      

      此时的attachedToProcess会返回false,因为此时还没和process绑定,所以会走到ActivityStackSupervisor的startSpecificActivityLocked方法:

      void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
          // Is this activity's application already running?
          final WindowProcessController wpc =
                  mService.getProcessController(r.processName, r.info.applicationInfo.uid);
            ...
          //如果Activity所需的进程已启动
          if (wpc != null && wpc.hasThread()) {
              try {
                  realStartActivityLocked(r, wpc, andResume, checkConfig);
                  return;
              } ...
          ...
            try {
              ...
              //如果是需要启动新进程
              final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                          r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
                  mService.mH.sendMessage(msg);
          }...
      }
      

      这里会根据mService.getProcessController是否能取到WindowProcessController来判断是否需要新建进程启动,getProcessController方法内是根据ActivityInfo的processName保存的WindowProcessController,因此我们回到创建ActivityInfo的地方看看这个processName是什么。

      ActivityInfo在ActivityStackSupervisor的resolveIntent方法中通过mService.getPackageManagerInternalLocked().resolveIntent方法生成的:

      PackageManagerInternal getPackageManagerInternalLocked() {
          if (mPmInternal == null) {
              mPmInternal = LocalServices.getService(PackageManagerInternal.class);
          }
          return mPmInternal;
      }
      

      可以看到,这里是通过LocalServices保存和获取对应的Internal的,前面的ActivityTaskManagerService也是通过它保存的ActivityTaskManagerInternal,那么这里的PackageManagerInternal实际上是什么呢?看名字我们分析这应该是和包管理相关的,顺着这个思路我们在PackageManagerService中找到了:

      LocalServices.addService(
              PackageManagerInternal.class, new PackageManagerInternalImpl());
      

      再往下就走到Package解析里去了,只需要知道这里的processName是根据包名生成的。

      startSpecificActivityLocked分了两个逻辑,一个是需要创建新进程的,一个是不需要的。

    • 依附于当前进程的Activity启动:realStartActivityLocked

      如果Activity所附属的进程已启动,则会直接进入realStartActivityLocked逻辑分支。

      boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
              boolean andResume, boolean checkConfig) throws RemoteException {
      
          ...
          r.setProcess(proc);
          ...
          ...
          // Create activity launch transaction.
          final ClientTransaction clientTransaction = ClientTransaction.obtain(
                  proc.getThread(), r.appToken);
          final DisplayContent dc = r.getDisplay().mDisplayContent;
          clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),...));
      
          // Set desired final state.
          final ActivityLifecycleItem lifecycleItem;
          if (andResume) {
              lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
          } else {
              lifecycleItem = PauseActivityItem.obtain();
          }
          clientTransaction.setLifecycleStateRequest(lifecycleItem);
      
          // Schedule transaction.
          mService.getLifecycleManager().scheduleTransaction(clientTransaction);
      
          ...
          // Perform OOM scoring after the activity state is set, so the process can be updated with the latest state.
          proc.onStartActivity(mService.mTopProcessState, r.info);
          ...
          return true;
      }
      

      scheduleTransaction来自于ClientLifecycleManager:

      void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
          final IApplicationThread client = transaction.getClient();
          transaction.schedule();
          if (!(client instanceof Binder)) {
              transaction.recycle();
          }
      }
      

      这里调用了ClientTransaction的schedule方法:

      public void schedule() throws RemoteException {
          mClient.scheduleTransaction(this);
      }
      

      mClient是一个IApplicationThread对象,通过ClientTransaction.obtain方法构造时传入:

      public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
          ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
          if (instance == null) {
              instance = new ClientTransaction();
          }
          instance.mClient = client;
          instance.mActivityToken = activityToken;
      
          return instance;
      }
      

      可见,这个IApplicationThread是proc.getThread(),proc来自于startSpecificActivityLocked方法中的wpc,它通过mService.getProcessController(r.processName, r.info.applicationInfo.uid)获取的,在进程创建的时候ActivityTaskManagerService会保存一个属于这个进程的WindowProcessController,它的Thread就是ApplicationThread(IApplicationThread实现类),ApplicationThread是ActivityThread的内部私有类,因此我们推测它的实例化都是在ActivityThread中完成的(也只能是这样),mService.getProcessController获取的ApplicationThread是怎么来的我们后面再看,现在先看一下它的scheduleTransaction方法:

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

      可见,就是调用的ActvityThread的scheduleTransaction方法,ActvityThread继承自ClientTransactionHandler,scheduleTransaction方法是在ClientTransactionHandler中定义并实现的:

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

      preExecute我们不用管,只是一些预处理操作回调,我们看见这里调用了sendMessage方法,它在ActivityThread中实现,最终是调用了mH.sendMessage方法,我们看一下mH的msg处理逻辑:

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

      这里调用了TransactionExecutor的execute方法来处理ClientTransaction:

      public void execute(ClientTransaction transaction) {
          ...
          executeCallbacks(transaction);
          executeLifecycleState(transaction);
          ...
      }
      

      这里的核心就是调用了两个方法,先看executeCallbacks:

      public void executeCallbacks(ClientTransaction transaction) {
          final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
          ...
          final int size = callbacks.size();
          for (int i = 0; i < size; ++i) {
              final ClientTransactionItem item = callbacks.get(i);
              ...
              item.execute(mTransactionHandler, token, mPendingActions);
              item.postExecute(mTransactionHandler, token, mPendingActions);
              ...
          }
      }
      

      这里会通过ClientTransaction的getCallbacks方法获取mActivityCallbacks,它是一个ClientTransactionItem集合,然后调用每一个ClientTransactionItem的execute方法,ClientTransactionItem是什么呢?还记得我们前面在realStartActivityLocked方法中调用ClientTransaction的addCallback方法添加的LaunchActivityItem.obtain()实例吗:

      public static LaunchActivityItem obtain(Intent intent, 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 isForward, ProfilerInfo profilerInfo,
              IBinder assistToken) {
          LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
          if (instance == null) {
              instance = new LaunchActivityItem();
          }
          setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
                  voiceInteractor, procState, state, persistentState, pendingResults,
                  pendingNewIntents, isForward, profilerInfo, assistToken);
      
          return instance;
      }
      

      所以只针对启动而言,会有一个LaunchActivityItem实例存在于mActivityCallbacks中,因此这里也会调用它的execute方法:

      public void execute(ClientTransactionHandler client, IBinder token,
              PendingTransactionActions pendingActions) {
          Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
          ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                  mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                  mPendingResults, mPendingNewIntents, mIsForward,
                  mProfilerInfo, client, mAssistToken);
          client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
          Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
      }
      

      client是前面的mTransactionHandler,在构造TransactionExecutor时传入:

      public final class ActivityThread extends ClientTransactionHandler {
            ...
            private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
            ...
      }
      

      因此client就是ActivityThread,它的handleLaunchActivity方法如下:

      public Activity handleLaunchActivity(ActivityClientRecord r,
              PendingTransactionActions pendingActions, Intent customIntent) {
          ...
          final Activity a = performLaunchActivity(r, customIntent);
            ...
          return a;
      }
      

      内部调用了performLaunchActivity方法创建Activity实例:

      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
          ActivityInfo aInfo = r.activityInfo;
          ...
          ComponentName component = r.intent.getComponent();
          ...
          //创建Activity的Context
          ContextImpl appContext = createBaseContextForActivity(r);
          Activity activity = null;
          try {
                    //创建Activity
              java.lang.ClassLoader cl = appContext.getClassLoader();
              activity = mInstrumentation.newActivity(
                      cl, component.getClassName(), r.intent);
              ...
          } ...
          try {
                //创建Application
              Application app = r.packageInfo.makeApplication(false, mInstrumentation);
              ...
              if (activity != null) {
                  ...
                  Window window = null;
                  ...
                  appContext.setOuterContext(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, r.configCallback,
                          r.assistToken);
                  ...
                  int theme = r.activityInfo.getThemeResource();
                  if (theme != 0) {
                      activity.setTheme(theme);
                  }
                    ...
                  //这里根据是否持久化调用onCreate的不同重载方法
                  if (r.isPersistable()) {
                      mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                  } else {
                      mInstrumentation.callActivityOnCreate(activity, r.state);
                  }
                  ...
              }
              ...
          } ...
          ...
          return activity;
      }
      

      可以看到,原来是在这里创建了Context、Activity和Application,而且调用了我们熟悉的onCreate方法。

      你可能会问,怎么没有调用onResume方法呢?还记得前面的TransactionExecutor的execute方法中调用executeCallbacks之后紧跟着还调用了executeLifecycleState方法吗。在executeLifecycleState方法中:

      private void executeLifecycleState(ClientTransaction transaction) {
          final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
          ...
          lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
          lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
      }
      

      getLifecycleStateRequest获取的就是前面realStartActivityLocked方法中设置的:

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

      在启动流程场景中andResume传入的是true,这里会根据是否需要显示设置不同的ActivityLifecycleItem,不管是ResumeActivityItem还是PauseActivityItem,其内部的execute逻辑和LaunchActivityItem都是一样的,最终都会通过mH调用到ActivityThread的相关方法里,在那些方法里会调用对应的Activity的生命周期方法,比如onResume或onPause,这个就不再看了。

      到此为止,我们看到了进程已存在的时候Activity是如何启动的,前面我们使用的WindowProcessController的ApplicationThread是进程创建时已经创建好的,那么这个ApplicationThread是怎样创建的呢?

    • 进程不存在时的Activity启动

      通过前面的分析,我们知道在ActivityStackSupervisor的startSpecificActivityLocked方法中,如果Activity需要依附的进程还未启动时会走另一个逻辑分支:

      final Message msg = PooledLambda.obtainMessage(
              ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
              r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
      mService.mH.sendMessage(msg);
      

      这里看到,mService,也就是ActivityTaskManagerService中也有一个mH,这里会给他发送一个消息,经过代码发现PooledLambda.obtainMessage获取的是一个空的Message,并没有设置what属性,而mH的handleMessage方法中并没有处理这种Message的逻辑:

      //ActivityTaskManagerService.H
      public void handleMessage(Message msg) {
          switch (msg.what) {
              case REPORT_TIME_TRACKER_MSG: {
                  AppTimeTracker tracker = (AppTimeTracker) msg.obj;
                  tracker.deliverResult(mContext);
              } break;
          }
      }
      

      那么它是怎么继续工作的呢?

      我们发现,这里使用Lambda语法传递了一个ActivityManagerInternal::startProcess函数,obtainMessage方法的其他参数是要传给startProcess的参数:

      static <A, B, C, D, E, F> Message obtainMessage(
              HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
              A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
          synchronized (Message.sPoolSync) {
              PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                      function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
                      null);
              return Message.obtain().setCallback(callback.recycleOnUse());
          }
      }
      

      acquire会创建或者复用一个PooledLambdaImpl对象,它持有一个mFunc字段,指向的是一个由编译器根据Lambda规则生成的Consumer实现类对象,内部持有了ActivityManagerInternal::startProcess函数,mArgs数组持有该函数需要的参数。

      mH调用sendMessage的时候内部会设置该msg的target为mH本身,然后根据Looper原理,sendMessage方法会走到msg.target的dispatchMessage方法(在Handler中定义并实现的):

      public void dispatchMessage(@NonNull Message msg) {
          if (msg.callback != null) {
              handleCallback(msg);
          } else {
              if (mCallback != null) {
                  if (mCallback.handleMessage(msg)) {
                      return;
                  }
              }
              handleMessage(msg);
          }
      }
      

      可以看到,因为我们前面给Message设置了callback,所以这里不会走Handler的handleMessage方法,而是走了handleCallback方法:

      private static void handleCallback(Message message) {
          message.callback.run();
      }
      

      可见在这里调用了callback的run方法,根据前面的分析,callback就是PooledLambdaImpl,它的run方法在其父类OmniFunction中实现:

      @Override
      public void run() {
          invoke(null, null, null, null, null, null, null, null, null);
      }
      

      invoke方法是在PooledLambdaImpl中实现:

      @Override
      R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
              Object a8, Object a9) {
          ...
          try {
              return doInvoke();
          } finally {
              if (isRecycleOnUse()) doRecycle();
              if (!isRecycled()) {
                  int argsSize = ArrayUtils.size(mArgs);
                  for (int i = 0; i < argsSize; i++) {
                      popArg(i);
                  }
              }
          }
      }
      

      这里又会调用doInvoke方法:

      private R doInvoke() {
          final int funcType = getFlags(MASK_FUNC_TYPE);
          final int argCount = LambdaType.decodeArgCount(funcType);
          final int returnType = LambdaType.decodeReturnType(funcType);
          switch (argCount) {
              ...
              case 6: {
                  switch (returnType) {
                      case LambdaType.ReturnType.VOID: {
                          ((HexConsumer) mFunc).accept(popArg(0), popArg(1),
                                  popArg(2), popArg(3), popArg(4), popArg(5));
                          return null;
                      }
                      case LambdaType.ReturnType.BOOLEAN: {
                          return (R) (Object) ((HexPredicate) mFunc).test(popArg(0),
                                  popArg(1), popArg(2), popArg(3), popArg(4), popArg(5));
                      }
                      case LambdaType.ReturnType.OBJECT: {
                          return (R) ((HexFunction) mFunc).apply(popArg(0), popArg(1),
                                  popArg(2), popArg(3), popArg(4), popArg(5));
                      }
                  }
              } break;
                    ...
          }
            ...
      }
      

      这里会根据参数的个数选择对应的执行分支,我们这里用的是6个参数函数,因此这里会走到6这个分支,再根据返回类型决定执行mFunc的哪个方法,这里因为传入的是VOID类型,所以会执行accept方法,jdk1.8编译器会根据Lambda规则生成Consumer实现代码,在accept中调用真正的函数,也就是ActivityManagerInternal::startProcess函数。

      那么调用哪个实例的startProcess函数呢?前面的obtainMessage方法中第二个参数传入的mService.mAmInternal是一个ActivityManagerInternal实例:

      mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
      

      我们找到LocalServices添加它的地方在ActivityManagerService的start方法中:

      LocalServices.addService(ActivityManagerInternal.class, new LocalService());
      

      所以真正调用的是LocalService的startProcess函数:

      @Override
      public void startProcess(String processName, ApplicationInfo info,
              boolean knownToBeDead, String hostingType, ComponentName hostingName) {
          ...
          synchronized (ActivityManagerService.this) {
              startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                      new HostingRecord(hostingType, hostingName),
                      false /* allowWhileBooting */, false /* isolated */,
                      true /* keepIfLarge */);
          }
          ...
      }
      

      之后经过以下的几次调用:

      //ActivityManagerService:
      final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, ...) {
          return mProcessList.startProcessLocked(processName, info, ...);
      }
      
      //ProcessList:
      final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,...){
          ...
          final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
            ...
          return success ? app : null;
      }
      
      final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
                  String abiOverride) {
          return startProcessLocked(app, hostingRecord,...);
      }
      
      boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,...) {
          ...
          //调用重载方法
          return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                   runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,                                            invokeWith,startTime);
      }
      
      boolean startProcessLocked(HostingRecord hostingRecord,
                  String entryPoint,
                  ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
                  String seInfo, String requiredAbi, String instructionSet, String invokeWith,
                  long startTime) {
           ...
           final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                  entryPoint, app,uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi,                          instructionSet,invokeWith, startTime);
             handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,startSeq,                         false);
             ...
      }
      

      最终来到了startProcess方法:

      private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
              ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
              String seInfo, String requiredAbi, String instructionSet, String invokeWith,
              long startTime) {
          try {
              Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                      app.processName);
              checkSlow(startTime, "startProcess: asking zygote to start proc");
              final Process.ProcessStartResult startResult;
              if (hostingRecord.usesWebviewZygote()) {
                  startResult = startWebView(entryPoint,
                          app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                          app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                          app.info.dataDir, null, app.info.packageName,
                          new String[] {PROC_START_SEQ_IDENT + app.startSeq});
              } else if (hostingRecord.usesAppZygote()) {
                  final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
      
                  startResult = appZygote.getProcess().start(entryPoint,
                          app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                          app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                          app.info.dataDir, null, app.info.packageName,
                          /*useUsapPool=*/ false,
                          new String[] {PROC_START_SEQ_IDENT + app.startSeq});
              } else {
                  startResult = Process.start(entryPoint,
                          app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                          app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                          app.info.dataDir, invokeWith, app.info.packageName,
                          new String[] {PROC_START_SEQ_IDENT + app.startSeq});
              }
              checkSlow(startTime, "startProcess: returned from zygote!");
              return startResult;
          } finally {
              Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
          }
      }
      

      这里有三种启动方式,通过Process来创建进程:

      public boolean usesAppZygote() {
          return mHostingZygote == APP_ZYGOTE;
      }
      public boolean usesWebviewZygote() {
          return mHostingZygote == WEBVIEW_ZYGOTE;
      }
      

      因为mHostingZygote属性只能通过构造HostingRecord时传入,ActivityManagerservice的startProcess方法中传入的HostingRecord是两个参数的构造方法创建的:

      public HostingRecord(String hostingType, ComponentName hostingName) {
          this(hostingType, hostingName, REGULAR_ZYGOTE);
      }
      

      此处传入的默认mHostingZygote是REGULAR_ZYGOTE,因此这里会走到Process.start启动逻辑:

      public static ProcessStartResult start(@NonNull final String processClass,...) {
          return ZYGOTE_PROCESS.start(processClass, ...);
      }
      

      再往下就是Process的启动逻辑了,又是另一个章节了,不是我们目前的目标。

      到现在为止,我们看到了新进程创建完成了,但是没看见Activity启动。回到最后一级startProcessLocked方法,startProcess方法之后调用了handleProcessStartedLocked方法:

      boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
              long expectedStartSeq, boolean procAttached) {
          ...
          mService.mPidsSelfLocked.put(app);
          ...
          return true;
      }
      

      这里就是进程创建完需要逻辑回调的地方。mService是ActivityManagerService,mPidsSelfLocked是一个PidMap,它的put方法如下:

      void put(ProcessRecord app) {
          synchronized (this) {
              mPidMap.put(app.pid, app);
          }
          mAtmInternal.onProcessMapped(app.pid, app.getWindowProcessController());
      }
      

      ActivityManagerService的mAtmInternal是通过key为ActivityTaskManagerInternal添加到LocalServices中的,它实际上是:

      //ActivityManagerService的start方法中:
      LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
      //ActivityManagerService构造方法中:
      mInternal = new LocalService();
      

      所以看LocalService的onProcessMapped方法:

      @Override
      public void onProcessMapped(int pid, WindowProcessController proc) {
          synchronized (mGlobalLock) {
              mProcessMap.put(pid, proc);
          }
      }
      

      还记得之前在startSpecificActivityLocked方法中分成两个逻辑时是根据什么判断的吗?正是ActivityTaskManagerService的getProcessController方法:

      WindowProcessController getProcessController(int pid, int uid) {
          final WindowProcessController proc = mProcessMap.getProcess(pid);
          if (proc == null) return null;
          if (UserHandle.isApp(uid) && proc.mUid == uid) {
              return proc;
          }
          return null;
      }
      

      因此进程创建完就会把新进程的WindowProcessController添加到mProcessMap中。但是现在添加太晚了啊,startSpecificActivityLocked的判断逻辑已经过去了呀,整个逻辑又怎么再次回到startSpecificActivityLocked中的呢?即现在无法再回到过去转而调用realStartActivityLocked了啊。

      这里就需要熟悉Zygote的知识了,Zygote进行fork出子进程后会调用到ActivityThread的main方法,Zygote分析得另开一文,这里只需要先这么记住。

      main方法里有这么两句:

      ActivityThread thread = new ActivityThread();
      thread.attach(false, startSeq);
      

      ActivityThread的attach方法中有:

      final IActivityManager mgr = ActivityManager.getService();
      mgr.attachApplication(mAppThread, startSeq);
      

      我们已经知道IActivityManager的实现类就是ActivityManagerService,它的attachApplication方法调用了attachApplicationLocked方法,这个方法内会调用mAtmInternal.attachApplication(app.getWindowProcessController())方法,前面我们知道mAtmInternal就是ActivityTaskManagerService.LocalService,它的attachApplication方法如下:

      public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
          synchronized (mGlobalLockWithoutBoost) {
              return mRootActivityContainer.attachApplication(wpc);
          }
      }
      

      这里又会调用到RootActivityContainer的attachApplication方法:

      boolean attachApplication(WindowProcessController app) throws RemoteException {
          final String processName = app.mName;
          boolean didSomething = false;
          for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
              final ActivityDisplay display = mActivityDisplays.get(displayNdx);
              final ActivityStack stack = display.getFocusedStack();
              if (stack != null) {
                    //获取目标栈中所有的需要显示的ActivityRecord
                  stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                  final ActivityRecord top = stack.topRunningActivityLocked();
                  final int size = mTmpActivityList.size();
                  for (int i = 0; i < size; i++) {
                      final ActivityRecord activity = mTmpActivityList.get(i);
                      if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                              && processName.equals(activity.processName)) {
                          try {
                              if (mStackSupervisor.realStartActivityLocked(activity, app,
                                      top == activity /* andResume */, true /* checkConfig */)) {
                                  didSomething = true;
                              }
                          } catch (RemoteException e) {
                              Slog.w(TAG, "Exception in new application when starting activity "
                                      + top.intent.getComponent().flattenToShortString(), e);
                              throw e;
                          }
                      }
                  }
              }
          }
          if (!didSomething) {
              ensureActivitiesVisible(null, 0, false /* preserve_windows */);
          }
          return didSomething;
      }
      

      可以看到,这里会取到焦点Stack,然后遍历其所有的Activity,调用ActivityStackSupervisor的realStartActivityLocked方法把它们创建或者恢复到正常生命周期。

      所以如果创建Activity之前需要启动新进程的情况的话,在进程启动完之后会直接调用realStartActivityLocked方法创建Activity,不再通过startSpecificActivityLocked方法的分支走了。

    • 总结

      我们根据API29的源码分析了整个Activity的启动过程,其中又分成新进程启动方式和当前进程内启动方式两种。分析过后,我认为在API29的源码逻辑下,整个Activity的启动逻辑分成4部分:

      • 角色进场

        1. 首先,Instrumentation负责以Binder的方式引出ActivityTaskManagerService,调用它的startActivity方法开启创建。

        2. 启动之后,它会根据启动结果值判断是否启动成功,如果失败会由它来负责爆出对应错误。

      • Stack信息的创建和维护

        1. 进入到ActivityTaskManagerService的startActivity逻辑后,它会通过内部的ActivityStartController创建或获取一个ActivityStarter,然后通过它的一系列链式方法把启动信息封装到一个ActivityStarter.Request对象中,然后调用ActivityStarter的execute方法。

        2. execute方法中会调用startActivityMayWait方法,它会通过一系列startActivity重载方法调用到startActivityUnchecked方法中,这个方法中会根据Activity的启动信息(ActivityRecord)找到所在的目标栈(mTargetStack),如果没找到则会创建一个,然后把这个栈对象设置成焦点栈并移到前台(如果Activity需要被显示的话)。

        3. 然后调用了RootActivityContainer的resumeFocusedStacksTopActivities方法。在这个方法中,会调用目标栈对象(ActivityStack)的resumeTopActivityUncheckedLocked方法,其内部又会调用resumeTopActivityInnerLocked方法,这个方法内部又会调用startSpecificActivityLocked方法,从这里开始分成上述的两种启动方式。

      • Activity创建逻辑

        在不需要创建新进程时,也就是在当前进程下创建Activity时,这部分逻辑的入口在ActivityStackSupervisor的realStartActivityLocked方法。

        1. 这个方法中会获取一个ClientTransaction对象,然后给它添加一个叫LaunchActivityItem的callback,再设置一个叫做ActivityLifecycleItem,如果是需要显示的Activity则设置ResumeActivityItem,否则设置PauseActivityItem。然后获取ActivityTaskManagerService的mLifecycleManager(ClientLifecycleManager),调用它的scheduleTransaction方法,把ClientTransaction对象传进去。
        2. scheduleTransaction方法中会调用ClientTransaction对象的schedule方法。
        3. schedule方法中会调用ApplicationThread的scheduleTransaction方法,ApplicationThread是ActivityThread的内部类,它继承自IApplicationThread.Stub,它的scheduleTransaction方法中调用了ActivityThread.this.scheduleTransaction方法,ActivityThread的scheduleTransaction方法实现在其父类ClientTransactionHandler中,在这里调用sendMessage方法,这个方法在ActivityThread里实现,在这里调用了mH的sendMessage方法,mH是ActivityThread.H。
        4. ActivityThread.H的handleMessage方法里处理EXECUTE_TRANSACTION这个信息,会调用TransactionExecutor的execute方法,传入的是ClientTransaction,这个方法里会调用executeCallbacks和executeLifecycleState方法。
        5. executeCallbacks内部会获取ClientTransaction的所有callback(ClientTransactionItem),然后调用每一个ClientTransactionItem的execute方法,自然也包括前面设置的LaunchActivityItem,它的execute方法中会调用传入的参数—ClientTransactionHandler—的handleLaunchActivity方法,传入的这个ClientTransactionHandler就是构造TransactionExecutor时传入的ActivityThread,因此handleLaunchActivity方法位于ActivityThread中,这个方法中又会调用performLaunchActivity方法,在其中会创建Activity实例、调用activity的attach、onCreate方法。
        6. executeLifecycleState方法逻辑中会找到设置的ActivityLifecycleItem,也就是ResumeActivityItem或PauseActivityItem,和LaunchActivityItem的流程一样,最终会调用activity的onResume或onPause方法。
      • 新进程启动方式中回调到Activity启动逻辑的流程

        1. 在新进程启动方式中需要Zygote的知识才能理解回到启动Activity的逻辑。只需要知道Zygote启动完成后会调用ActivityThread的main函数。
        2. 在main函数中会调用ActivityThread的attach方法,它会调用到ActivityManagerService的attachApplication方法,这个方法又会调用ActivityTaskManagerService.LocalService的attachApplication方法。
        3. 然后又调用RootActivityContainer的attachApplication方法,在这个方法中会把焦点Stack内部的Activity信息依次传入ActivityStackSupervisor的realStartActivityLocked方法,到这就进入了同样的Activity的创建逻辑。

    相关文章

      网友评论

          本文标题:Activity启动流程分析

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