【Android Framework系列】第6章 AMS原理之Launcer启动流程

news2024/11/25 14:46:47

1 前言

我们在上一章节【Android Framework系列】第5章 AMS启动流程中简单的分析了AMS的启动流程,这一章节我们来了解一下,通过AMS是怎么完成Activity的启动

下面我们通过Launcher启动一起来看看Activity的启动流程

本文基于Android10(Q)的源码做分析

2 Launcher启动流程

2.1 SystemServer启动AMS,准备启动Launcher

由【Android Framework系列】第5章 AMS启动流程我们可以知道:

  1. 手机开机后会启动system_server进程,然后调用SystemServermain()方法,
  2. main()方法中通过startBootstrapServices()启动AMS。
  3. 之后通过startOtherServices()方法调用AMSsystemReady(),告知AMS可以执行第三方代码。
  4. systemReady()方法中,通过调用startHomeOnAllDisplays()来启动初始Activity。

2.2 进程启动与Activity启动前奏

2.2.1 ActivityManagerService的startHomeOnAllDisplays()

我们就从startHomeOnAllDisplays()方法开始继续分析:
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

8967  
8968      public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
......
				  // 调用ActivityTaskManagerService的startHomeOnAllDisplays方法(就是启动Launcher的Activity)
9084              mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
......
9144      }

这里mAtmInternalActivityTaskManagerService对象,而startHomeOnAllDisplays()方法直接调用的是RootActivityContainer对象的该同名方法。

2.2.2 ActivityTaskManagerService的startHomeOnAllDisplays()

/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

6691          @Override
6692          public boolean startHomeOnAllDisplays(int userId, String reason) {
6693              synchronized (mGlobalLock) {
					  // 此处会调用mRootWindowContainer对象的startHomeOnAllDisplays函数
					  // 这边的mRootWindowContainer参数的值是从WindowManagerService中的mRoot参数对应的对象
					  // mRootWindowContainer参数是通过AMS的setWindowManager函数调用,进而调用ATMS.LocalServices的setWindowManager函数得到的
					  // 因此,此处需要注意的是RootWindowContainer对象的mWmService参数对应的是WindowManagerService对象
					  // mService参数对应的是ActivityTaskManagerService对象
6694                  return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
6695              }
6696          }

/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

332      boolean startHomeOnAllDisplays(int userId, String reason) {
333          boolean homeStarted = false;
    		 // getChildCount获取显示设备数目,这个主要从mChildren参数中获取对应的数量
    		 // mChildren是一个WindowList的一个对象,其包含的数据是在setWindowManager函数被调用时,
    		 // 从DisplayManagerService中获取到的Display的数目,
334          for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
				 // 获取到对应新建的DisplayContent的displayId
335              final int displayId = mActivityDisplays.get(i).mDisplayId;
				 // 调用startHomeOnDisplay函数
336              homeStarted |= startHomeOnDisplay(userId, reason, displayId);
337          }
338          return homeStarted;
339      }
......
366      boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
367              boolean fromHomeKey) {
368          // Fallback to top focused display if the displayId is invalid.
			 // 由于DisplayManagerService中获取到的displayId不为INVALID_DISPLAY,因此此处判断条件不满足
			 // 如果displayId无效,则退回到顶层拥有焦点的显示设备
369          if (displayId == INVALID_DISPLAY) {
370              displayId = getTopDisplayFocusedStack().mDisplayId;
371          }
372  
373          Intent homeIntent = null;
374          ActivityInfo aInfo = null;
375          if (displayId == DEFAULT_DISPLAY) {
				 // 获取Lancher的第一个页面的intent,其category为Intent.CATEGORY_HOME
376              homeIntent = mService.getHomeIntent();
				 // 通过intent找到Launcher中AndroidManifest对应的activity标签,解析出相应的activityInfo和applicationInfo信息
377              aInfo = resolveHomeActivity(userId, homeIntent);
378          } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
				 // 多屏显示功能,可以参考官网说明
				 // https://source.android.google.cn/devices/tech/display/multi_display/system-decorations#launcher
379              Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
380              aInfo = info.first;
381              homeIntent = info.second;
382          }
383          if (aInfo == null || homeIntent == null) {
384              return false;
385          }
386  
387          if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
388              return false;
389          }
390  
			 // 在启动前,校验是否满足启动条件,大概校验了displayId的有效性、对应activity的启动模式、是否处于工厂测试模式等等
392          homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
393          homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
			 // 传入的fromHomeKey的值为false
395          if (fromHomeKey) {
396              homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
397          }
398          // Update the reason for ANR debugging to verify if the user activity is the one that
399          // actually launched.
400          final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
401                  aInfo.applicationInfo.uid) + ":" + displayId;
			 // 转到ActivityStartController类中继续调用startHomeActivity方法
402          mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
403                  displayId);
404          return true;
405      }
......
412      ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
413          final int flags = ActivityManagerService.STOCK_PM_FLAGS;
414          final ComponentName comp = homeIntent.getComponent();
415          ActivityInfo aInfo = null;
416          try {
417              if (comp != null) {
418                  // Factory test.
419                  aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
420              } else {
421                  final String resolvedType =
422                          homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
423                  final ResolveInfo info = AppGlobals.getPackageManager()
424                          .resolveIntent(homeIntent, resolvedType, flags, userId);
425                  if (info != null) {
426                      aInfo = info.activityInfo;
427                  }
428              }
429          } catch (RemoteException e) {
430              // ignore
431          }
432  
433          if (aInfo == null) {
434              Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
435              return null;
436          }
437  
438          aInfo = new ActivityInfo(aInfo);
439          aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
440          return aInfo;
441      }

从上述这段代码可以看到,这边主要是依次做了四件事情

  1. RootActivityContainer类中,此处会针对于多显示设备的情况,启动多个Launcher主界面,当然在这边,我们只分析默认显示设备的情况。
  2. 通过ATMSgetHomeIntent函数,获取启动Activity的一个Intent对象
  3. resolveHomeActivity函数通过PMS获取启动界面的ActivityInfo对象
  4. 通过ActivityStartController对象的startHomeActivity函数来启动对应的Activity

2.2.3 ActivityStartController的startHomeActivity()

我们继续看看ActivityStartController里的startHomeActivity()方法:
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

......
171      void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
			 // 创建一个ActivityOptions的对象
172          final ActivityOptions options = ActivityOptions.makeBasic();
			 // FULLSCREEN模式启动Activity
173          options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
174          if (!ActivityRecord.isResolverActivity(aInfo.name)) {
				 // 判断当前是否拥有多个Launcher并处于选择Launcher状态,否的话设置ACTIVITY_TYPE_HOME属性,直接启动Launcher的Activity
178              options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
179          }
180          options.setLaunchDisplayId(displayId);
			 // 执行启动任务
181          mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
182                  .setOutActivity(tmpOutRecord)
183                  .setCallingUid(0)
184                  .setActivityInfo(aInfo)
185                  .setActivityOptions(options.toBundle())
186                  .execute();
187          mLastHomeActivityStartRecord = tmpOutRecord[0];
188          final ActivityDisplay display =
189                  mService.mRootActivityContainer.getActivityDisplay(displayId);
190          final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
191          if (homeStack != null && homeStack.mInResumeTopActivity) {
192              // If we are in resume section already, home activity will be initialized, but not
193              // resumed (to avoid recursive resume) and will stay that way until something pokes it
194              // again. We need to schedule another resume.
195              mSupervisor.scheduleResumeTopActivities();
196          }
197      }
......

执行开始任务,obtainStarter()方法内从缓存池内获取ActivityStarter对象(没有则创建一个),通过execute()方法执行Activity的启动

2.2.4 ActivityStarter的execute()

/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

......
509      int execute() {
510          try {
511              // TODO(b/64750076): Look into passing request directly to these methods to allow
512              // for transactional diffs and preprocessing.
513              if (mRequest.mayWait) {
514                  return startActivityMayWait(mRequest.caller, mRequest.callingUid,
515                          mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
516                          mRequest.intent, mRequest.resolvedType,
517                          mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
518                          mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
519                          mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
520                          mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
521                          mRequest.inTask, mRequest.reason,
522                          mRequest.allowPendingRemoteAnimationRegistryLookup,
523                          mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
524              } else {
525                  return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
526                          mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
527                          mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
528                          mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
529                          mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
530                          mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
531                          mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
532                          mRequest.outActivity, mRequest.inTask, mRequest.reason,
533                          mRequest.allowPendingRemoteAnimationRegistryLookup,
534                          mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
535              }
536          } finally {
537              onExecutionComplete();
538          }
539      }
......

mRequest.mayWait在执行execute()前没有赋值,默认false,我们继续看startActivity()方法:

2.2.5 ActivityStarter的startActivity()

/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

......
611      private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
612              String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
613              IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
614              IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
615              String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
616              SafeActivityOptions options,
617              boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
618              TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
619              PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
......
			 // 创建被启动的Activity对应的ActivityRecord对象
899          ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
900                  callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
901                  resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
902                  mSupervisor, checkedOptions, sourceRecord);
903          if (outActivity != null) {
904              outActivity[0] = r;
905          }
906  
907          if (r.appTimeTracker == null && sourceRecord != null) {
908              // If the caller didn't specify an explicit time tracker, we want to continue
909              // tracking under any it has.
910              r.appTimeTracker = sourceRecord.appTimeTracker;
911          }
912  
913          final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
			 // 如果我们启动的activity与当前恢复的activity的uid不同,请检查是否允许应用程序切换。
917          if (voiceSession == null && (stack.getResumedActivity() == null
918                  || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
919              if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
920                      realCallingPid, realCallingUid, "Activity start")) {
921                  if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
922                      mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
923                              sourceRecord, startFlags, stack, callerApp));
924                  }
925                  ActivityOptions.abort(checkedOptions);
926                  return ActivityManager.START_SWITCHES_CANCELED;
927              }
928          }
929  
930          mService.onStartActivitySetDidAppSwitch();
931          mController.doPendingActivityLaunches(false);
932  
933          final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
934                  true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
935          mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
936          return res;
937      }
......
1386      private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1387                  IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1388                  int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1389                  ActivityRecord[] outActivity, boolean restrictedBgActivity) {
1390          int result = START_CANCELED;
1391          final ActivityStack startedActivityStack;
1392          try {
1393              mService.mWindowManager.deferSurfaceLayout();
1394              result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
1395                      startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
1396          } finally {
......
1431          }
1432  
1433          postStartActivityProcessing(r, result, startedActivityStack);
1434  
1435          return result;
1436      }

......
 // Note: This method should only be called from {@link startActivity}.
1464      private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1465              IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1466              int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1467              ActivityRecord[] outActivity, boolean restrictedBgActivity) {
......
			  // 如果正在启动的activity与当前在顶部的activity相同,那么我们需要检查它是否应该只启动一次
1625          final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
1626          final ActivityRecord topFocused = topStack.getTopActivity();
1627          final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1628          final boolean dontStart = top != null && mStartActivity.resultTo == null
1629                  && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1630                  && top.mUserId == mStartActivity.mUserId
1631                  && top.attachedToProcess()
1632                  && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1633                  || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1634                  // This allows home activity to automatically launch on secondary display when
1635                  // display added, if home was the top activity on default display, instead of
1636                  // sending new intent to the home activity on default display.
1637                  && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
1638          if (dontStart) {
1639              // For paranoia, make sure we have correctly resumed the top activity.
1640              topStack.mLastPausedActivity = null;
1641              if (mDoResume) {
1642                  mRootActivityContainer.resumeFocusedStacksTopActivities();
1643              }
1644              ActivityOptions.abort(mOptions);
1645              if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1646                  // We don't need to start a new activity, and the client said not to do
1647                  // anything if that is the case, so this is it!
1648                  return START_RETURN_INTENT_TO_CALLER;
1649              }
1650  
1651              deliverNewIntent(top);
1652  
1653              // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1654              // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
1655              mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
1656                      mPreferredDisplayId, topStack);
1657  
1658              return START_DELIVERED_TO_TOP;
1659          }
......
			  // 往ActivityStack中写入启动的activity记录,同时更新TaskRecord信息
1700          mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1701                  mOptions);
1702          if (mDoResume) {
1703              final ActivityRecord topTaskActivity =
1704                      mStartActivity.getTaskRecord().topRunningActivityLocked();
1705              if (!mTargetStack.isFocusable()
1706                      || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1707                      && mStartActivity != topTaskActivity)) {
					  // 如果activity无焦点的,我们不能恢复它,但仍然希望确保它在启动时时变得可见(这也将触发入场动画)。
					  // 此外,我们不希望在当前有覆盖层的Task中恢复activity,
					  // 因为正在启动的activity只需要处于可见的暂停状态,直到覆盖层被移除。
1714                  mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
1715                  // Go ahead and tell window manager to execute app transition for this activity
1716                  // since the app transition will not be triggered through the resume channel.
1717                  mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
1718              } else {
1719                  // If the target stack was not previously focusable (previous top running activity
1720                  // on that stack was not visible) then any prior calls to move the stack to the
1721                  // will not update the focused stack.  If starting the new activity now allows the
1722                  // task stack to be focusable, then ensure that we now update the focused stack
1723                  // accordingly.
1724                  if (mTargetStack.isFocusable()
1725                          && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
1726                      mTargetStack.moveToFront("startActivityUnchecked");
1727                  }
1728                  mRootActivityContainer.resumeFocusedStacksTopActivities(
1729                          mTargetStack, mStartActivity, mOptions);
1730              }
1731          } else if (mStartActivity != null) {
1732              mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
1733          }
1734          mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
1735  
1736          mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1737                  preferredWindowingMode, mPreferredDisplayId, mTargetStack);
1738  
1739          return START_SUCCESS;
1740      }
1741  
......

它调用了RootActivityContainerresumeFocusedStacksTopActivities()方法,启动目标ActivityStack的最顶层activity。我们继续看RootActivityContainer类的resumeFocusedStacksTopActivities()

2.2.6 RootActivityContainer的resumeFocusedStacksTopActivities()

/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java


1148      boolean resumeFocusedStacksTopActivities(
1149              ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
......
1156          if (targetStack != null && (targetStack.isTopStackOnDisplay()
1157                  || getTopDisplayFocusedStack() == targetStack)) {
1158              result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1159          }
1160  
1161          for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
......
1185              if (!resumedOnDisplay) {
1186                  // In cases when there are no valid activities (e.g. device just booted or launcher
1187                  // crashed) it's possible that nothing was resumed on a display. Requesting resume
1188                  // of top activity in focused stack explicitly will make sure that at least home
1189                  // activity is started and resumed, and no recursion occurs.
1190                  final ActivityStack focusedStack = display.getFocusedStack();
1191                  if (focusedStack != null) {
1192                      focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1193                  }
1194              }
1195          }
1196  
1197          return result;
1198      }

我们接着往下追踪,它调用了ActivityStackresumeTopActivityInnerLocked()方法。

2.2.7 ActivityStack的resumeTopActivityUncheckedLocked()

/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

2565      boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
......
2572          try {
2573              // Protect against recursion.
2574              mInResumeTopActivity = true;
2575              result = resumeTopActivityInnerLocked(prev, options);
......
2588          } finally {
2589              mInResumeTopActivity = false;
2590          }
2591  
2592          return result;
2593      }
......

2613      @GuardedBy("mService")
2614      private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
			  // 暂停上一个activity
2744          boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
2745          if (mResumedActivity != null) {
2746              if (DEBUG_STATES) Slog.d(TAG_STATES,
2747                      "resumeTopActivityLocked: Pausing " + mResumedActivity);
2748              pausing |= startPausingLocked(userLeaving, false, next, false);
2749          }
			  // 如果最近的activity没有历史记录,但由于设备进入睡眠状态而被停止,而不是停止+销毁,我们需要确保销毁它,因为我们正在使一个新的activity处于最顶层。
2781          if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
2782                  !mLastNoHistoryActivity.finishing) {
2783              if (DEBUG_STATES) Slog.d(TAG_STATES,
2784                      "no-history finish of " + mLastNoHistoryActivity + " on new resume");
2785              requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
2786                      null, "resume-no-history", false);
2787              mLastNoHistoryActivity = null;
2788          }
2789  
2790          if (prev != null && prev != next && next.nowVisible) {
				  // 下一个activity已经可见,所以现在隐藏前一个activity的窗口,以便我们可以尽快显示新的activity。
				  // 我们只有在前一个结束时才这样做,这意味着它在resume的那个之上,所以快速隐藏它是有好处的。
				  // 否则,我们希望按照正常的方式显示resume的activity,
				  // 这样我们就可以根据新activity是否全屏来决定是否应该隐藏以前的activity
2800              if (prev.finishing) {
2801                  prev.setVisibility(false);
2802                  if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2803                          "Not waiting for visible to hide: " + prev
2804                          + ", nowVisible=" + next.nowVisible);
2805              } else {
2806                  if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2807                          "Previous already visible but still waiting to hide: " + prev
2808                          + ", nowVisible=" + next.nowVisible);
2809              }
2810  
2811          }
2812  
2813          // Launching this app's activity, make sure the app is no longer
2814          // considered stopped.
2815          try {
2816              AppGlobals.getPackageManager().setPackageStoppedState(
2817                      next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
2818          } catch (RemoteException e1) {
2819          } catch (IllegalArgumentException e) {
2820              Slog.w(TAG, "Failed trying to unstop package "
2821                      + next.packageName + ": " + e);
2822          }
			  // 我们正在启动下一个activity,所以告诉window manager,
			  // 上一个activity很快就会被隐藏。这样,它可以知道在计算所需的屏幕方向时忽略它。
2827          boolean anim = true;
2828          final DisplayContent dc = getDisplay().mDisplayContent;
2829          if (prev != null) {
2830              if (prev.finishing) {
2831                  if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2832                          "Prepare close transition: prev=" + prev);
2833                  if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
2834                      anim = false;
2835                      dc.prepareAppTransition(TRANSIT_NONE, false);
2836                  } else {
2837                      dc.prepareAppTransition(
2838                              prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_CLOSE
2839                                      : TRANSIT_TASK_CLOSE, false);
2840                  }
2841                  prev.setVisibility(false);
2842              } else {
2843                  if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2844                          "Prepare open transition: prev=" + prev);
2845                  if (mStackSupervisor.mNoAnimActivities.contains(next)) {
2846                      anim = false;
2847                      dc.prepareAppTransition(TRANSIT_NONE, false);
2848                  } else {
2849                      dc.prepareAppTransition(
2850                              prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_OPEN
2851                                      : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND
2852                                              : TRANSIT_TASK_OPEN, false);
2853                  }
2854              }
2855          } else {
2856              if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
2857              if (mStackSupervisor.mNoAnimActivities.contains(next)) {
2858                  anim = false;
2859                  dc.prepareAppTransition(TRANSIT_NONE, false);
2860              } else {
2861                  dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
2862              }
2863          }
2864  
2865          if (anim) {
2866              next.applyOptionsLocked();
2867          } else {
2868              next.clearOptionsLocked();
2869          }
2870  
2871          mStackSupervisor.mNoAnimActivities.clear();
2872  
2873          if (next.attachedToProcess()) {
			  // 只有启动过的activity才会进入此分支
......
3025          } else {
3026              // Whoops, need to restart this activity!
3027              if (!next.hasBeenLaunched) {
3028                  next.hasBeenLaunched = true;
3029              } else {
3030                  if (SHOW_APP_STARTING_PREVIEW) {
						  // 冷启动的过渡页,在这里会载入manifest配置的主题背景,
						  // 如果没有的话,默认白屏或黑屏
3031                      next.showStartingWindow(null /* prev */, false /* newTask */,
3032                              false /* taskSwich */);
3033                  }
3034                  if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
3035              }
3036              if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
3037              mStackSupervisor.startSpecificActivityLocked(next, true, true);
3038          }
3039  
3040          return true;
3041      }

通过源码,我们可以得知:

  1. 先对上一个Activity执行pause操作
  2. 再启动目标activity
  3. 最终进入到了ActivityStackSupervior.startSpecificActivityLocked()方法中。
  4. 在启动Activity之前,调用了next.showStartingWindow()方法来展示一个window
    这就是冷启动时出现白屏的原因

2.3 进程启动与Activity启动的节点

2.3.1 ActivityStackSupervisor的startSpecificActivityLocked()

我们继续往下追踪ActivityStackSupervisorstartSpecificActivityLocked()方法:
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

......
956      void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
957          // Is this activity's application already running?
			 // 根据进程名和进程id判断目标进程是否已经创建,如果没有则代表进程未创建
958          final WindowProcessController wpc =
959                  mService.getProcessController(r.processName, r.info.applicationInfo.uid);
960  
961          boolean knownToBeDead = false;
			 // 如果进程已经创建,这里直接调用realStartActivityLocked去启动Activity
962          if (wpc != null && wpc.hasThread()) {
963              try {
964                  realStartActivityLocked(r, wpc, andResume, checkConfig);
965                  return;
966              } catch (RemoteException e) {
967                  Slog.w(TAG, "Exception when starting activity "
968                          + r.intent.getComponent().flattenToShortString(), e);
969              }
......
973              knownToBeDead = true;
974          }
......
979          if (getKeyguardController().isKeyguardLocked()) {
980              r.notifyUnknownVisibilityLaunched();
981          }
982  
983          try {
......
				 // 走到这里说明目标进程未创建,这里使用handler发送消息给ActivityManagerService类,让AMS创建一个新的进程
				 // 通过发送消息的方式,可避免在ATMS锁被持有的情况下,调用AMS时可能出现的死锁
990              final Message msg = PooledLambda.obtainMessage(
991                      ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
992                      r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
993              mService.mH.sendMessage(msg);
994          } finally {
995              Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
996          }
997      }
......

上面这段方法里有个很重要的判断:if(wpc != null && wpc.hasThread())。通过进程名和application uid 获取的WindowProcessController对象进行校验,判断要启动的activity进程是否已启动,分别进行两个关键逻辑:
1. 启动未进程时,启动进程
2. 进程已启动时,启动Activity

显然,app第一次启动时,进程还不存在,首先先得进程启动

2.4 进程启动

从上面代码可知,PooledLambda.obtainMessage()通过Handler,发送了一条Message,以避免在ATMS锁被持有的情况下调用AMS时可能出现的死锁。这条Message调用的是ActivityManagerServicestartProcess()方法,实际调用的是startProcessLocked()方法,我们直接从它看起:

2.4.1 startProcessLocked()

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

3022      final ProcessRecord startProcessLocked(String processName,
3023              ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3024              HostingRecord hostingRecord, boolean allowWhileBooting,
3025              boolean isolated, boolean keepIfLarge) {
3026          return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
3027                  hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3028                  null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3029                  null /* crashHandler */);
3030      }

这里调用的是ProcessList类里的startProcessLocked()的方法,我们继续往下看。

/frameworks/base/services/core/java/com/android/server/am/ProcessList.java

......
1848      @GuardedBy("mService")
1849      final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
1850              boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
1851              boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1852              String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
1853          long startTime = SystemClock.elapsedRealtime();
1854          ProcessRecord app;
......
        	  // 以下三种情况,我们不需要做任何额外的处理
        	  // (1) 存在一个application 记录
        	  // (2) 调用者认为它仍然存活,或者没有线程对象连接到它,所以我们知道它没有crash
        	  // (3) 有一个pid分配给它,所以它要么正在启动,要么已经运行
1900          if (app != null && app.pid > 0) {
1901              if ((!knownToBeDead && !app.killed) || app.thread == null) {
					  // 我们已经有应用程序在运行,或者正在等待它出现(我们有一个pid,但还没有它的线程),所以保持它
1904                  if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
1905                  // If this is a new package in the process, add the package to the list
1906                  app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
1907                  checkSlow(startTime, "startProcess: done, added package to proc");
1908                  return app;
1909              }
1910  
1911              // An application record is attached to a previous process,
1912              // clean it up now.
1913              if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
1914              checkSlow(startTime, "startProcess: bad proc running, killing");
1915              ProcessList.killProcessGroup(app.uid, app.pid);
1916              mService.handleAppDiedLocked(app, true, true);
1917              checkSlow(startTime, "startProcess: done killing old proc");
1918          }
1919  
1920          if (app == null) {
1921              checkSlow(startTime, "startProcess: creating new process record");
				  // 创建一条ProcessRecord
1922              app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
1923              if (app == null) {
1924                  Slog.w(TAG, "Failed making new process record for "
1925                          + processName + "/" + info.uid + " isolated=" + isolated);
1926                  return null;
1927              }
1928              app.crashHandler = crashHandler;
1929              app.isolatedEntryPoint = entryPoint;
1930              app.isolatedEntryPointArgs = entryPointArgs;
1931              checkSlow(startTime, "startProcess: done creating new process record");
1932          } else {
1933              // If this is a new package in the process, add the package to the list
1934              app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
1935              checkSlow(startTime, "startProcess: added package to existing proc");
1936          }
1937  
1938          // If the system is not ready yet, then hold off on starting this
1939          // process until it is.
1940          if (!mService.mProcessesReady
1941                  && !mService.isAllowedWhileBooting(info)
1942                  && !allowWhileBooting) {
1943              if (!mService.mProcessesOnHold.contains(app)) {
1944                  mService.mProcessesOnHold.add(app);
1945              }
1946              if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
1947                      "System not ready, putting on hold: " + app);
1948              checkSlow(startTime, "startProcess: returning with proc on hold");
1949              return app;
1950          }
1951  
1952          checkSlow(startTime, "startProcess: stepping in to startProcess");
			  // 创建一个进程。
1953          final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
1954          checkSlow(startTime, "startProcess: done starting proc!");
1955          return success ? app : null;
1956      }
......

可以看到,在启动一个新的进程时,有两个比较重要的步骤:

  1. 通过new ProcessRecordLocked()方法首先创建一条进程记录
  2. 然后再通过startProcessLocked()方法去创建一个进程。

/frameworks/base/services/core/java/com/android/server/am/ProcessList.java

......
1427      @GuardedBy("mService")
1428      boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1429              boolean disableHiddenApiChecks, boolean mountExtStorageFull,
1430              String abiOverride) {
......
				  // 
1619              final String entryPoint = "android.app.ActivityThread";
1620  
1621              return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
1622                      runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1623                      startTime);
1624          } catch (RuntimeException e) {
1625              Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
......
1633              mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1634                      false, false, true, false, false, app.userId, "start failure");
1635              return false;
1636          }
1637      }

这里请注意一下entryPoint这个变量的值————android.app.ActivityThread,它会经过一段漫长的调用链,最终在RuntimeInit这个类中发挥它的作用。
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java

 @GuardedBy("mService")
1640      boolean startProcessLocked(HostingRecord hostingRecord,
1641              String entryPoint,
1642              ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1643              String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1644              long startTime) {
1645          app.pendingStart = true;
1646          app.killedByAm = false;
1647          app.removed = false;
1648          app.killed = false;
......
1657          final long startSeq = app.startSeq = ++mProcStartSeqCounter;
1658          app.setStartParams(uid, hostingRecord, seInfo, startTime);
1659          app.setUsingWrapper(invokeWith != null
1660                  || SystemProperties.get("wrap." + app.processName) != null);
1661          mPendingStarts.put(startSeq, app);
1662  
1663          if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
				  // 默认以异步方式启动
1666              mService.mProcStartHandler.post(() -> {
1667                  try {
1668                      final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
1669                              entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1670                              app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1671                      synchronized (mService) {
1672                          handleProcessStartedLocked(app, startResult, startSeq);
1673                      }
1674                  } catch (RuntimeException e) {
1675                      synchronized (mService) {
1676                          Slog.e(ActivityManagerService.TAG, "Failure starting process "
1677                                  + app.processName, e);
1678                          mPendingStarts.remove(startSeq);
1679                          app.pendingStart = false;
1680                          mService.forceStopPackageLocked(app.info.packageName,
1681                                  UserHandle.getAppId(app.uid),
1682                                  false, false, true, false, false, app.userId, "start failure");
1683                      }
1684                  }
1685              });
1686              return true;
1687          } else {
1688              try {
1689                  final Process.ProcessStartResult startResult = startProcess(hostingRecord,
1690                          entryPoint, app,
1691                          uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
1692                          invokeWith, startTime);
1693                  handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1694                          startSeq, false);
1695              } catch (RuntimeException e) {
1696                  Slog.e(ActivityManagerService.TAG, "Failure starting process "
1697                          + app.processName, e);
1698                  app.pendingStart = false;
1699                  mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1700                          false, false, true, false, false, app.userId, "start failure");
1701              }
1702              return app.pid > 0;
1703          }
......
1798      private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
1799              ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1800              String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1801              long startTime) {
1802          try {
1803              Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
1804                      app.processName);
1805              checkSlow(startTime, "startProcess: asking zygote to start proc");
1806              final Process.ProcessStartResult startResult;
				  // hostingRecord初始化参数为null,
				  // 并未指定mHostingZygote属性,因此会进入最后一个分支
1807              if (hostingRecord.usesWebviewZygote()) {
1808                  startResult = startWebView(entryPoint,
1809                          app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1810                          app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1811                          app.info.dataDir, null, app.info.packageName,
1812                          new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1813              } else if (hostingRecord.usesAppZygote()) {
1814                  final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
1815  
1816                  startResult = appZygote.getProcess().start(entryPoint,
1817                          app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1818                          app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1819                          app.info.dataDir, null, app.info.packageName,
1820                          /*useUsapPool=*/ false,
1821                          new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1822              } else {
1823                  startResult = Process.start(entryPoint,
1824                          app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1825                          app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1826                          app.info.dataDir, invokeWith, app.info.packageName,
1827                          new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1828              }
1829              checkSlow(startTime, "startProcess: returned from zygote!");
1830              return startResult;
1831          } finally {
1832              Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1833          }
1834      }

hostingRecord初始化参数为null,并未指定mHostingZygote属性,因此会进入最后一个分支,调用方法Process.start()

2.4.2 Process的start()方法

/frameworks/base/core/java/android/os/Process.java

521      public static ProcessStartResult start(@NonNull final String processClass,
522                                             @Nullable final String niceName,
523                                             int uid, int gid, @Nullable int[] gids,
524                                             int runtimeFlags,
525                                             int mountExternal,
526                                             int targetSdkVersion,
527                                             @Nullable String seInfo,
528                                             @NonNull String abi,
529                                             @Nullable String instructionSet,
530                                             @Nullable String appDataDir,
531                                             @Nullable String invokeWith,
532                                             @Nullable String packageName,
533                                             @Nullable String[] zygoteArgs) {
534          return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
535                      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
536                      abi, instructionSet, appDataDir, invokeWith, packageName,
537                      /*useUsapPool=*/ true, zygoteArgs);
538      }

其中ZYGOTE_PROCESS是一个ZygoteProcess对象,它实际调用的是ZygoteProcess里的start()方法。
/frameworks/base/core/java/android/os/ZygoteProcess.java

314      public final Process.ProcessStartResult start(@NonNull final String processClass,
315                                                    final String niceName,
316                                                    int uid, int gid, @Nullable int[] gids,
317                                                    int runtimeFlags, int mountExternal,
318                                                    int targetSdkVersion,
319                                                    @Nullable String seInfo,
320                                                    @NonNull String abi,
321                                                    @Nullable String instructionSet,
322                                                    @Nullable String appDataDir,
323                                                    @Nullable String invokeWith,
324                                                    @Nullable String packageName,
325                                                    boolean useUsapPool,
326                                                    @Nullable String[] zygoteArgs) {
327          // TODO (chriswailes): Is there a better place to check this value?
328          if (fetchUsapPoolEnabledPropWithMinInterval()) {
329              informZygotesOfUsapPoolStatus();
330          }
331  
332          try {
333              return startViaZygote(processClass, niceName, uid, gid, gids,
334                      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
335                      abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
336                      packageName, useUsapPool, zygoteArgs);
337          } catch (ZygoteStartFailedEx ex) {
338              Log.e(LOG_TAG,
339                      "Starting VM process through Zygote failed");
340              throw new RuntimeException(
341                      "Starting VM process through Zygote failed", ex);
342          }
343      }
......
541      private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
542                                                        @Nullable final String niceName,
543                                                        final int uid, final int gid,
544                                                        @Nullable final int[] gids,
545                                                        int runtimeFlags, int mountExternal,
546                                                        int targetSdkVersion,
547                                                        @Nullable String seInfo,
548                                                        @NonNull String abi,
549                                                        @Nullable String instructionSet,
550                                                        @Nullable String appDataDir,
551                                                        @Nullable String invokeWith,
552                                                        boolean startChildZygote,
553                                                        @Nullable String packageName,
554                                                        boolean useUsapPool,
555                                                        @Nullable String[] extraArgs)
556                                                        throws ZygoteStartFailedEx {
557          ArrayList<String> argsForZygote = new ArrayList<>();
558  
559          // --runtime-args, --setuid=, --setgid=,
560          // and --setgroups= must go first
561          argsForZygote.add("--runtime-args");
562          argsForZygote.add("--setuid=" + uid);
563          argsForZygote.add("--setgid=" + gid);
564          argsForZygote.add("--runtime-flags=" + runtimeFlags);
565          if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
566              argsForZygote.add("--mount-external-default");
567          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
568              argsForZygote.add("--mount-external-read");
569          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
570              argsForZygote.add("--mount-external-write");
571          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
572              argsForZygote.add("--mount-external-full");
573          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
574              argsForZygote.add("--mount-external-installer");
575          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
576              argsForZygote.add("--mount-external-legacy");
577          }
578  
579          argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
580  
581          // --setgroups is a comma-separated list
582          if (gids != null && gids.length > 0) {
583              StringBuilder sb = new StringBuilder();
584              sb.append("--setgroups=");
585  
586              int sz = gids.length;
587              for (int i = 0; i < sz; i++) {
588                  if (i != 0) {
589                      sb.append(',');
590                  }
591                  sb.append(gids[i]);
592              }
593  
594              argsForZygote.add(sb.toString());
595          }
596  
597          if (niceName != null) {
598              argsForZygote.add("--nice-name=" + niceName);
599          }
600  
601          if (seInfo != null) {
602              argsForZygote.add("--seinfo=" + seInfo);
603          }
604  
605          if (instructionSet != null) {
606              argsForZygote.add("--instruction-set=" + instructionSet);
607          }
608  
609          if (appDataDir != null) {
610              argsForZygote.add("--app-data-dir=" + appDataDir);
611          }
612  
613          if (invokeWith != null) {
614              argsForZygote.add("--invoke-with");
615              argsForZygote.add(invokeWith);
616          }
617  
618          if (startChildZygote) {
619              argsForZygote.add("--start-child-zygote");
620          }
621  
622          if (packageName != null) {
623              argsForZygote.add("--package-name=" + packageName);
624          }
625  
626          argsForZygote.add(processClass);
627  
628          if (extraArgs != null) {
629              Collections.addAll(argsForZygote, extraArgs);
630          }
631  
632          synchronized(mLock) {
633              // The USAP pool can not be used if the application will not use the systems graphics
634              // driver.  If that driver is requested use the Zygote application start path.
635              return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
636                                                useUsapPool,
637                                                argsForZygote);
638          }
639      }

值得注意的是上面这段代码的openZygoteSocketIfNeeded()这个方法,它采用socket通信方式,尝试连接路径为/dev/socket/、名称为zygote的服务端。
zygoteSendArgsAndGetResult()方法里实际调用了attemptZygoteSendArgsAndGetResult()方法,内容如下:

/frameworks/base/core/java/android/os/ZygoteProcess.java

422      private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
423              ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
424          try {
425              final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
426              final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
427  
428              zygoteWriter.write(msgStr);
429              zygoteWriter.flush();
430  
431              // Always read the entire result from the input stream to avoid leaving
432              // bytes in the stream for future process starts to accidentally stumble
433              // upon.
434              Process.ProcessStartResult result = new Process.ProcessStartResult();
435              result.pid = zygoteInputStream.readInt();
436              result.usingWrapper = zygoteInputStream.readBoolean();
437  
438              if (result.pid < 0) {
439                  throw new ZygoteStartFailedEx("fork() failed");
440              }
441  
442              return result;
443          } catch (IOException ex) {
444              zygoteState.close();
445              Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
446                      + ex.toString());
447              throw new ZygoteStartFailedEx(ex);
448          }
449      }

请注意上述方法的zygoteWriter这个变量,它负责将进程启动参数发送给服务端,由服务端去孵化进程。那么,这个服务端到底是哪个类呢?
答案是ZygoteServer.java

ZygoteServer会在系统启动的时候,创建一个Socket服务端,用于接收客户端的fork请求。ZygoteServer在初始化结束后,会调用runSelectLoop()方法,用于处理客户端的消息。当客户端请求fork进程时,runSelectLoop()方法会转交给ZygoteConnection类的processOneCommand()方法去处理。
Zygote相关可以参考前面我们分析过的【Android Framework系列】第3章 Zygote进程相关

下面我们继续看

2.4.3 ZygoteConnection的processOneCommand()方法

/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

129      Runnable processOneCommand(ZygoteServer zygoteServer) {
130          String args[];
131          ZygoteArguments parsedArgs = null;
132          FileDescriptor[] descriptors;
......
267          pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
268                  parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
269                  parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
270                  parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
271  
272          try {
273              if (pid == 0) {
274                  // in child
275                  zygoteServer.setForkChild();
276  
277                  zygoteServer.closeServerSocket();
278                  IoUtils.closeQuietly(serverPipeFd);
279                  serverPipeFd = null;
280  
281                  return handleChildProc(parsedArgs, descriptors, childPipeFd,
282                          parsedArgs.mStartChildZygote);
283              } else {
284                  // In the parent. A pid < 0 indicates a failure and will be handled in
285                  // handleParentProc.
286                  IoUtils.closeQuietly(childPipeFd);
287                  childPipeFd = null;
288                  handleParentProc(pid, descriptors, serverPipeFd);
289                  return null;
290              }
291          } finally {
292              IoUtils.closeQuietly(childPipeFd);
293              IoUtils.closeQuietly(serverPipeFd);
294          }
295      }

通过静态方法Zygote.forkAndSpecialize()进行程序fork

2.4.4 Zygote的forkAndSpecialize()方法

/frameworks/base/core/java/com/android/internal/os/Zygote.java

234      public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
235              int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
236              int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
237              int targetSdkVersion) {
238          ZygoteHooks.preFork();
239          // Resets nice priority for zygote process.
240          resetNicePriority();
241          int pid = nativeForkAndSpecialize(
242                  uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
243                  fdsToIgnore, startChildZygote, instructionSet, appDataDir);
244          // Enable tracing as soon as possible for the child process.
245          if (pid == 0) {
246              Zygote.disableExecuteOnly(targetSdkVersion);
247              Trace.setTracingEnabled(true, runtimeFlags);
248  
249              // Note that this event ends at the end of handleChildProc,
250              Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
251          }
252          ZygoteHooks.postForkCommon();
253          return pid;
254      }
255  
256      private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
257              int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
258              int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
259              String appDataDir);

上述Zygote类在这个过程中主要做了以下几点工作:

  1. 调用dalvikZygoteHookspreFrok进行预处理,主要是停止4个Daemon子线程HeapTaskDaemonReferenceQueueDaemonFinalizerDaemonFinalizerWatchdogDaemon,等待所有的子线程结束,最后完成gc堆的初始化工作。
  2. 调用com_android_internal_os_zygote.cpp中的nativeForkAndSpecialize方法,主要工作是通过linux机制fork一个子进程,以及进程的一些资源处理selinux权限处理JAVA堆线程的一些处理
  3. 调用ZygoteHookspostForkCommon方法,启动Zygote的4个Daemon线程

在执行forkAndSpecialize()方法后,代码将继续执行ZygoteConnection中的handleChildProc()这个方法。

2.4.5 ZygoteConnection的handleChildProc()方法

/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

560      private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
561              FileDescriptor pipeFd, boolean isZygote) {
......
589          if (parsedArgs.mInvokeWith != null) {
590              WrapperInit.execApplication(parsedArgs.mInvokeWith,
591                      parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
592                      VMRuntime.getCurrentInstructionSet(),
593                      pipeFd, parsedArgs.mRemainingArgs);
594  
595              // Should not get here.
596              throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
597          } else {
598              if (!isZygote) {
					 // 进入此分支
599                  return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
600                          parsedArgs.mRemainingArgs, null /* classLoader */);
601              } else {
602                  return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
603                          parsedArgs.mRemainingArgs, null /* classLoader */);
604              }
605          }
606      }

我们继续往下看ZygoteInit.zygoteInit() 方法

2.4.6 ZygoteInit的zygoteInit()方法

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

972      public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
973              ClassLoader classLoader) {
			 // 初始化运行环境
981          RuntimeInit.commonInit();
			 // 启动binder线程池
982          ZygoteInit.nativeZygoteInit();
			 // 程序入口函数
983          return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
984      }

2.4.7 RuntimeInit.applicationInit()方法

继续看程序入口函数RuntimeInit.applicationInit()

284      protected static Runnable findStaticMain(String className, String[] argv,
285              ClassLoader classLoader) {
286          Class<?> cl;
287  
288          try {
289              cl = Class.forName(className, true, classLoader);
290          } catch (ClassNotFoundException ex) {
291              throw new RuntimeException(
292                      "Missing class when invoking static main " + className,
293                      ex);
294          }
295  
296          Method m;
297          try {
298              m = cl.getMethod("main", new Class[] { String[].class });
299          } catch (NoSuchMethodException ex) {
300              throw new RuntimeException(
301                      "Missing static main on " + className, ex);
302          } catch (SecurityException ex) {
303              throw new RuntimeException(
304                      "Problem getting static main on " + className, ex);
305          }
306  
307          int modifiers = m.getModifiers();
308          if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
309              throw new RuntimeException(
310                      "Main method is not public and static on " + className);
311          }
......
319          return new MethodAndArgsCaller(m, argv);
320      }
......
343      protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
344              ClassLoader classLoader) {
......
350          nativeSetExitWithoutCleanup(true);
......
354          VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
355          VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
356  
357          final Arguments args = new Arguments(argv);
358  
359          // The end of of the RuntimeInit event (see #zygoteInit).
360          Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
361  
362          // Remaining arguments are passed to the start class's static main
363          return findStaticMain(args.startClass, args.startArgs, classLoader);
364      }

这里通过反射获得了className变量中的main()方法,并传递给MethodAndArgsCaller用于构造一个Runnable。只要执行此Runnable,就会开始执行className变量中的main()方法。

className变量的值究竟是什么呢?

还记得我们前文重点强调的entryPoint这个变量吗?不记得的读者请自行返回再查看一下。android.app.ActivityThread就是我们要执行的目标类。

ActivityThreadmain方法的调用,标识着 应用已全部完成进程的创建和初始化过程,下面将进入ApplicationActivity的创建与启动流程。

2.5 Application启动

从2.4中,我们知道ActivityThreadmain()方法被调用了,程序成功被创建并启动。

2.5.1 ActivityThread的main()

/frameworks/base/core/java/android/app/ActivityThread.java

7310      public static void main(String[] args) {
7311          Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
7312  
7313          // Install selective syscall interception
7314          AndroidOs.install();
7315  
7316          // CloseGuard defaults to true and can be quite spammy.  We
7317          // disable it here, but selectively enable it later (via
7318          // StrictMode) on debug builds, but using DropBox, not logs.
7319          CloseGuard.setEnabled(false);
			  // 初始化应用中需要使用的系统路径
7321          Environment.initForCurrentUser();
7322  
7323          // Make sure TrustedCertificateStore looks in the right place for CA certificates
			  // 为应用设置当前用户的CA证书保存的位置
7324          final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
7325          TrustedCertificateStore.setDefaultUserDirectory(configDir);
7326  
			  // 设置进程的名称
7327          Process.setArgV0("<pre-initialized>");
			  // 主线程Looper准备
7329          Looper.prepareMainLooper();
......
			  // 创建ActivityThread 对象
7342          ActivityThread thread = new ActivityThread();
7343          thread.attach(false, startSeq);
7344  
7345          if (sMainThreadHandler == null) {
7346              sMainThreadHandler = thread.getHandler();
7347          }
......
			  // 主线程Looper,开启消息循环
7356          Looper.loop();
7357  
7358          throw new RuntimeException("Main thread loop unexpectedly exited");
7359      }
......

2.5.2 ActivityThread的attach()

main()方法内调用了attach()方法
/frameworks/base/core/java/android/app/ActivityThread.java

7071      private void attach(boolean system, long startSeq) {
7072          sCurrentActivityThread = this;
7073          mSystemThread = system;
7074          if (!system) {
7075              android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
7076                                                      UserHandle.myUserId());
				  // 把对象mAppThread(Binder)放到了RuntimeInit类中的静态变量mApplicationObject中
7077              RuntimeInit.setApplicationObject(mAppThread.asBinder());
7078              final IActivityManager mgr = ActivityManager.getService();
7079              try {
					  // 关键:通过Binder调用AMS的attachApplication()方法
7080                  mgr.attachApplication(mAppThread, startSeq);
7081              } catch (RemoteException ex) {
7082                  throw ex.rethrowFromSystemServer();
7083              }
......
7106          } else {
7107              // Don't set application object here -- if the system crashes,
7108              // we can't display an alert, we just want to die die die.
7109              android.ddm.DdmHandleAppName.setAppName("system_process",
7110                      UserHandle.myUserId());
7111              try {
7112                  mInstrumentation = new Instrumentation();
7113                  mInstrumentation.basicInit(this);
7114                  ContextImpl context = ContextImpl.createAppContext(
7115                          this, getSystemContext().mPackageInfo);
7116                  mInitialApplication = context.mPackageInfo.makeApplication(true, null);
7117                  mInitialApplication.onCreate();
7118              } catch (Exception e) {
7119                  throw new RuntimeException(
7120                          "Unable to instantiate Application():" + e.toString(), e);
7121              }
7122          }
......
7144      }
7145  

ActivityThread类的attach方法内,通过binder调用AMSattachApplication方法进行Application的初始化。我们来看看:

2.5.3 ActivityManagerService的attachApplication()

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

5179      @Override
5180      public final void attachApplication(IApplicationThread thread, long startSeq) {
5181          if (thread == null) {
5182              throw new SecurityException("Invalid application interface");
5183          }
5184          synchronized (this) {
5185              int callingPid = Binder.getCallingPid();
5186              final int callingUid = Binder.getCallingUid();
5187              final long origId = Binder.clearCallingIdentity();
5188              attachApplicationLocked(thread, callingPid, callingUid, startSeq);
5189              Binder.restoreCallingIdentity(origId);
5190          }
5191      }

2.5.4 ActivityManagerService的attachApplicationLocked()

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

4767      private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
4768              int pid, int callingUid, long startSeq) {
......
5046              if (app.isolatedEntryPoint != null) {
5047                  // This is an isolated process which should just call an entry point instead of
5048                  // being bound to an application.
5049                  thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
5050              } else if (instr2 != null) {
					  // 1.调用ApplicationThread的bindApplication去初始化Application
5051                  thread.bindApplication(processName, appInfo, providers,
5052                          instr2.mClass,
5053                          profilerInfo, instr2.mArguments,
5054                          instr2.mWatcher,
5055                          instr2.mUiAutomationConnection, testMode,
5056                          mBinderTransactionTrackingEnabled, enableTrackAllocation,
5057                          isRestrictedBackupMode || !normalMode, app.isPersistent(),
5058                          new Configuration(app.getWindowProcessController().getConfiguration()),
5059                          app.compat, getCommonServicesLocked(app.isolated),
5060                          mCoreSettingsObserver.getCoreSettingsLocked(),
5061                          buildSerial, autofillOptions, contentCaptureOptions);
5062              } else {
5063                  thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
5064                          null, null, null, testMode,
5065                          mBinderTransactionTrackingEnabled, enableTrackAllocation,
5066                          isRestrictedBackupMode || !normalMode, app.isPersistent(),
5067                          new Configuration(app.getWindowProcessController().getConfiguration()),
5068                          app.compat, getCommonServicesLocked(app.isolated),
5069                          mCoreSettingsObserver.getCoreSettingsLocked(),
5070                          buildSerial, autofillOptions, contentCaptureOptions);
5071              }
5072              if (profilerInfo != null) {
5073                  profilerInfo.closeFd();
5074                  profilerInfo = null;
5075              }
5076  
5077              // Make app active after binding application or client may be running requests (e.g
5078              // starting activities) before it is ready.
5079              app.makeActive(thread, mProcessStats);
5080              checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
5081              mProcessList.updateLruProcessLocked(app, false, null);
5082              checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
5083              app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5084          } catch (Exception e) {
......
5093              return false;
5094          }
5095  
5096          // Remove this record from the list of starting applications.
5097          mPersistentStartingProcesses.remove(app);
5098          if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
5099                  "Attach application locked removing on hold: " + app);
5100          mProcessesOnHold.remove(app);
5101  
5102          boolean badApp = false;
5103          boolean didSomething = false;
5104  
5105          // See if the top visible activity is waiting to run in this process...
5106          if (normalMode) {
5107              try {
					  // 2.去启动Activity
5108                  didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
5109              } catch (Exception e) {
5110                  Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5111                  badApp = true;
5112              }
5113          }
......
5176          return true;
5177      }

上面代码主要做了两件事:

  1. 调用了ApplicationThreadbindApplication()方法去初始化Application,又是一次跨进程调用。
  2. 通过ATMS去启动目标Activity
    先来分析ApplicationThreadbindApplication()方法

2.5.5 ActivityThread的bindApplication()

/frameworks/base/core/java/android/app/ActivityThread.java

996          public final void bindApplication(String processName, ApplicationInfo appInfo,
997                  List<ProviderInfo> providers, ComponentName instrumentationName,
998                  ProfilerInfo profilerInfo, Bundle instrumentationArgs,
999                  IInstrumentationWatcher instrumentationWatcher,
1000                  IUiAutomationConnection instrumentationUiConnection, int debugMode,
1001                  boolean enableBinderTracking, boolean trackAllocation,
1002                  boolean isRestrictedBackupMode, boolean persistent, Configuration config,
1003                  CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
1004                  String buildSerial, AutofillOptions autofillOptions,
1005                  ContentCaptureOptions contentCaptureOptions) {
......
				  // 通过handler发消息,启动Application
1053              sendMessage(H.BIND_APPLICATION, data);
1054          }
......
1855              switch (msg.what) {
1856                  case BIND_APPLICATION:
1857                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1858                      AppBindData data = (AppBindData)msg.obj;
1859                      handleBindApplication(data);
1860                      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1861                      break;
				  }

......

 @UnsupportedAppUsage
6122      private void handleBindApplication(AppBindData data) {
......
6379              final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
6380                      appContext.getClassLoader(), false, true, false);
......
6385              final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
6386                      appContext.getOpPackageName());
6387  
6388              try {
6389                  final ClassLoader cl = instrContext.getClassLoader();
					  // 创建仪表
6390                  mInstrumentation = (Instrumentation)
6391                      cl.loadClass(data.instrumentationName.getClassName()).newInstance();
6392              } catch (Exception e) {
......
6396              }
6397  
6398              final ComponentName component = new ComponentName(ii.packageName, ii.name);
				  // 初始化仪表盘
6399              mInstrumentation.init(this, instrContext, appContext, component,
6400                      data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
......
6412          }
......
6425          Application app;
......
6428          try {
6429              // If the app is being launched for full backup or restore, bring it up in
6430              // a restricted environment with the base application class.
				  // 创建Application
6431              app = data.info.makeApplication(data.restrictedBackupMode, null);
......
6451              try {
6452                  mInstrumentation.onCreate(data.instrumentationArgs);
6453              }
6454              catch (Exception e) {
......
6458              }
6459              try {
					  // 调用Application的onCreate方法
6460                  mInstrumentation.callApplicationOnCreate(app);
6461              } catch (Exception e) {
...
6467              }
6468          } finally {
....
6475          }
6497      }
......

主要做了三件事:

  1. 创建仪表盘。
  2. 使用LoadedApk创建一个Application,不过最终还是使用的仪表盘利用反射创建的Application类。
  3. 使用仪表盘初始化Application,点击去可以查看下mInstrumentation.callApplicationOnCreate()方法。

2.5.6 Instrumentation的callApplicationOnCreate()

/frameworks/base/core/java/android/app/Instrumentation.java

1181      public void callApplicationOnCreate(Application app) {
1182          app.onCreate();
1183      }

到这里,Application即初始化完成。

2.5.7 Application启动后,跟着继续启动第一个Activity

AMSattachApplicationLocked()做了两件事:

  1. Application创建已经完成。
  2. 通过ATMS启动程序的第一个Activity
    拿我们继续往下看Activity的启动:

这里mAtmInternal.attachApplication(app.getWindowProcessController())中的mAtmInternalLocalService类对象是ATMS的子类,继承自ActivityTaskManagerInternal

/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

6078      final class LocalService extends ActivityTaskManagerInternal {
......
6866          @Override
6867          public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6868              synchronized (mGlobalLockWithoutBoost) {
6869                  return mRootActivityContainer.attachApplication(wpc);
6870              }
6871          }
		  }

这个方法只做了一件事,调用RootActivityContainerattachApplication()方法,我们继续看看:
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

768      boolean attachApplication(WindowProcessController app) throws RemoteException {
769          final String processName = app.mName;
770          boolean didSomething = false;
771          for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
772              final ActivityDisplay display = mActivityDisplays.get(displayNdx);
773              final ActivityStack stack = display.getFocusedStack();
774              if (stack != null) {
775                  stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
776                  final ActivityRecord top = stack.topRunningActivityLocked();
777                  final int size = mTmpActivityList.size();
778                  for (int i = 0; i < size; i++) {
779                      final ActivityRecord activity = mTmpActivityList.get(i);
780                      if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
781                              && processName.equals(activity.processName)) {
782                          try {
783                              if (mStackSupervisor.realStartActivityLocked(activity, app,
784                                      top == activity /* andResume */, true /* checkConfig */)) {
785                                  didSomething = true;
786                              }
787                          } catch (RemoteException e) {
788                              Slog.w(TAG, "Exception in new application when starting activity "
789                                      + top.intent.getComponent().flattenToShortString(), e);
790                              throw e;
791                          }
792                      }
793                  }
794              }
795          }
796          if (!didSomething) {
797              ensureActivitiesVisible(null, 0, false /* preserve_windows */);
798          }
799          return didSomething;
800      }

可以看到这里调用了ActivityStackSupervisorrealStartActivityLocked()方法
到这里就和我们在2.3中ActivityStackSupervisorstartSpecificActivityLocked()方法内的第二个分支一致了。
有两个分支:

  1. 进程未启动,则使用handler发message给AMS通知创建进程;(2.4中已分析)
  2. 进程已启动,则启动Activity。

下面我们来看看Activity的启动:

2.6 Activity启动

2.6.1 ActivityStackSupervisor的realStartActivityLocked()

startSpecificActivityLocked()方法内调用了realStartActivityLocked(),我们来看看这个方法:
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

705      boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
706              boolean andResume, boolean checkConfig) throws RemoteException {
......
					 // 创建一个Activity启动事务,同时传入proc.getThread(),
					 // 该对象实际为ApplicationThread
828                  final ClientTransaction clientTransaction = ClientTransaction.obtain(
829                          proc.getThread(), r.appToken);
830  
831                  final DisplayContent dc = r.getDisplay().mDisplayContent;
					 // 把LaunchActivityItem加入事务中,
					 // 后面会调用到该类的handleLaunchActivity()方法
832                  clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
833                          System.identityHashCode(r), r.info,
834                          // TODO: Have this take the merged configuration instead of separate global
835                          // and override configs.
836                          mergedConfiguration.getGlobalConfiguration(),
837                          mergedConfiguration.getOverrideConfiguration(), r.compat,
838                          r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
839                          r.icicle, r.persistentState, results, newIntents,
840                          dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
841                                  r.assistToken));
842  
843                  // Set desired final state.
844                  final ActivityLifecycleItem lifecycleItem;
845                  if (andResume) {
846                      lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
847                  } else {
848                      lifecycleItem = PauseActivityItem.obtain();
849                  }
850                  clientTransaction.setLifecycleStateRequest(lifecycleItem);
851  
					 // 在这里启动事务
853                  mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
929          return true;
930      }

重点代码做了注释,可以看到在这段代码中,主要是创建事务,同时传入ApplicationThread,而ApplicationThread继承于Binder,这里传入目的主要后面用来跟目标APP进程通信。然后就是启动事务,mService.getLifecycleManager()方法返回的是ClientLifecycleManager对象,接下来继续分析ClientLifecycleManagerscheduleTransaction()方法

2.6.2 scheduleTransaction()

/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

45      void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
46          final IApplicationThread client = transaction.getClient();
47          transaction.schedule();
48          if (!(client instanceof Binder)) {
49              // If client is not an instance of Binder - it's a remote call and at this point it is
50              // safe to recycle the object. All objects used for local calls will be recycled after
51              // the transaction is executed on client in ActivityThread.
52              transaction.recycle();
53          }
54      }

ClientLifecycleManager类的scheduleTransaction()方法中可以明确看到,这里实际调用了ClientTransaction对象的schedule()方法,进入到ClientTransactionschedule()方法继续分析。

/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

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

ClientTransaction类的schedule()方法里,又调用了mClientscheduleTransaction()方法,而这个mClient实际就是在创建Activity启动事务时传入的ApplicationThread对象,也就是说,这里开始从AMS进程跨进程调用ApplicationThreadscheduleTransaction()方法**(第二次跨进程)**,接下来进入到ApplicationThreadscheduleTransaction()方法中分析。

/frameworks/base/core/java/android/app/ActivityThread.java

904      private class ApplicationThread extends IApplicationThread.Stub {
1665          public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
1666              ActivityThread.this.scheduleTransaction(transaction);
1667          }
		 }

ApplicationThreadActivityThread的内部类,继承于IApplicationThread.Stub,而IApplicationThread.Stub又继承于Binder,所以本质还是一个Binder,用来在ActivityThreadAMS之间通信。继续分析scheduleTransaction()方法,这里又调用了ActivityThreadscheduleTransaction()方法,实际上ActivityThread是父类ClientTransactionHandler的方法,点进去分析。

/frameworks/base/core/java/android/app/ClientTransactionHandler.java

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

在这个方法里发送handler消息H.EXECUTE_TRANSACTION,并且Message中的obj就是启动 Activity的事务对象。而这个Handler的具体实现是ActivityThread中的H对象,接着找到接收handle消息的地方继续分析。

2.6.3 ActivityThread中处理Handler消息

/frameworks/base/core/java/android/app/ActivityThread.java

1853          public void handleMessage(Message msg) {
1854              if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1855              switch (msg.what) {
......
2014                  case EXECUTE_TRANSACTION:
2015                      final ClientTransaction transaction = (ClientTransaction) msg.obj;
2016                      mTransactionExecutor.execute(transaction);
2017                      if (isSystem()) {
2018                          // Client transactions inside system process are recycled on the client side
2019                          // instead of ClientLifecycleManager to avoid being cleared before this
2020                          // message is handled.
2021                          transaction.recycle();
2022                      }
2023                      // TODO(lifecycler): Recycle locally scheduled transactions.
2024                      break;
......
2031              }

接收handler消息的地方定义在ActivityThread类中,在这里,又调用了TransactionExecutorexecute()方法,点进去继续分析

2.6.4 TransactionExecutor的execute

/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

69      public void execute(ClientTransaction transaction) {
......
95          executeCallbacks(transaction);
96  
97          executeLifecycleState(transaction);
98          mPendingActions.clear();
99          if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
100      }
......
104      public void executeCallbacks(ClientTransaction transaction) {
......
124          final int size = callbacks.size();
125          for (int i = 0; i < size; ++i) {
126              final ClientTransactionItem item = callbacks.get(i);
127              if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
128              final int postExecutionState = item.getPostExecutionState();
129              final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
130                      item.getPostExecutionState());
131              if (closestPreExecutionState != UNDEFINED) {
132                  cycleToPath(r, closestPreExecutionState, transaction);
133              }
				 // item的类型其实就是LaunchActivityItem
135              item.execute(mTransactionHandler, token, mPendingActions);
136              item.postExecute(mTransactionHandler, token, mPendingActions);
......
148          }
149      }

executeCallback()方法中,会遍历事务中的callback并执行execute方法,这些callbacks是在前面创建Activity启动事务时添加,添加的callback对象其实就是ClientTransactionItem类的子类LaunchActivityItem的对象。
所以,item.execute(mTransactionHandler, token, mPendingActions),就是调用了LaunchActivityItem类的execute()方法,进入LaunchActivityItem类的execute()方法继续分析。

2.6.5 LaunchActivityItem的execute()

/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java

76      public void execute(ClientTransactionHandler client, IBinder token,
77              PendingTransactionActions pendingActions) {
78          Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
79          ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
80                  mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
81                  mPendingResults, mPendingNewIntents, mIsForward,
82                  mProfilerInfo, client, mAssistToken);
			// 注意这里:启动Activity
83          client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
84          Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
85      }

LaunchActivityItem类的execute()方法里,调用了client.handleLaunchActivity()方法,这里的clientClientTransactionHandler类型,而ClientTransactionHandler的实现类是ActivityThread,所以这里又回到了ActivityThread类,并调用了handleLaunchActivity()方法,继续分析。

2.6.6 ActivityThread的handleLaunchActivity()

/frameworks/base/core/java/android/app/ActivityThread.java

3380      @Override
3381      public Activity handleLaunchActivity(ActivityClientRecord r,
3382              PendingTransactionActions pendingActions, Intent customIntent) {
......
			  // 初始化 Activity 的 WindowManager,每一个 Activity 都会对应一个“窗口”
3404          WindowManagerGlobal.initialize();
			  // 这里是重点
3409          final Activity a = performLaunchActivity(r, customIntent);
......
3430          return a;
3431      }

2.6.7 ActivityThread的performLaunchActivity()

/frameworks/base/core/java/android/app/ActivityThread.java

3158      /**  Core implementation of activity launch. */
3159      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
3178          ContextImpl appContext = createBaseContextForActivity(r);
3179          Activity activity = null;
3180          try {
				  // 1.通过反射创建目标 Activity 对象
3181              java.lang.ClassLoader cl = appContext.getClassLoader();
3182              activity = mInstrumentation.newActivity(
3183                      cl, component.getClassName(), r.intent);
3184              StrictMode.incrementExpectedActivityCount(activity.getClass());
3185              r.intent.setExtrasClassLoader(cl);
3186              r.intent.prepareToEnterProcess();
3187              if (r.state != null) {
3188                  r.state.setClassLoader(cl);
3189              }
3190          } catch (Exception e) {
......
3196          }
3197  
3198          try {
3199              Application app = r.packageInfo.makeApplication(false, mInstrumentation);
.......
3209              if (activity != null) {
......
					  // 2.创建window
3217                  Window window = null;
3218                  if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
3219                      window = r.mPendingRemoveWindow;
3220                      r.mPendingRemoveWindow = null;
3221                      r.mPendingRemoveWindowManager = null;
3222                  }
3223                  appContext.setOuterContext(activity);
					  // 3.调用 attach 方法建立 Activity 与 Context 之间的联系,
					  // 创建 PhoneWindow 对象,并与 Activity 进行关联操作
3224                  activity.attach(appContext, this, getInstrumentation(), r.token,
3225                          r.ident, app, r.intent, r.activityInfo, title, r.parent,
3226                          r.embeddedID, r.lastNonConfigurationInstances, config,
3227                          r.referrer, r.voiceInteractor, window, r.configCallback,
3228                          r.assistToken);
.......
3236                  int theme = r.activityInfo.getThemeResource();
3237                  if (theme != 0) {
						  // 设置主题
3238                      activity.setTheme(theme);
3239                  }
3240  
3241                  activity.mCalled = false;
					  // 4.通过 Instrumentation 最终调用 Activity 的 onCreate 方法
3242                  if (r.isPersistable()) {
3243                      mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
3244                  } else {
3245                      mInstrumentation.callActivityOnCreate(activity, r.state);
3246                  }
3247                  if (!activity.mCalled) {
3248                      throw new SuperNotCalledException(
3249                          "Activity " + r.intent.getComponent().toShortString() +
3250                          " did not call through to super.onCreate()");
3251                  }
3252                  r.activity = activity;
3253              }
......
3266          } catch (Exception e) {
......
3272          }
3273  
3274          return activity;
3275      }

主要代码已经加了注释,主要做了以下这些事情,

  1. 使用反射创建目标Activity对象;
  2. 创建PhoneWindow对象,
  3. 调用attach方法绑定Activity
  4. 调用ActivityonCreate方法

步骤4中,是通过Instrumentation来调用的ActivityonCreate()方法,点进去看下callActivityOnCreate()方法。

2.6.8 Instrumentation的callActivityOnCreate()

/frameworks/base/core/java/android/app/Instrumentation.java

1297      public void callActivityOnCreate(Activity activity, Bundle icicle) {
1298          prePerformCreate(activity);
1299          activity.performCreate(icicle);
1300          postPerformCreate(activity);
1301      }
......
1310      public void callActivityOnCreate(Activity activity, Bundle icicle,
1311              PersistableBundle persistentState) {
1312          prePerformCreate(activity);
1313          activity.performCreate(icicle, persistentState);
1314          postPerformCreate(activity);
1315      }

可以看到调用了ActivityperformCreate()方法,进入performCreate()方法查看:
/frameworks/base/core/java/android/app/Activity.java

7795      final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
			  // 在这里调用了Activity的生命周期onCreate方法
7799          if (persistentState != null) {
7800              onCreate(icicle, persistentState);
7801          } else {
7802              onCreate(icicle);
7803          }
......
7812      }

到这里,Activity已经被创建调用了onCreate()方法,并开始了生命周期的回调

3 总结

由于涉及的类和方法太多,我就简单总结一下Launcher启动的整体流程:

  1. SystemServerAMS启动后,AMS开始启动Launcher.
  2. AMS判断目标Activity所属进程是否存在,不存在就去通知Zygote进程创建一个新的进程。
  3. 新的进程进入ActivityThreadmain()入口,初始化Looper,并通知AMS进程去初始化Application
  4. 同时AMS又去执行Activity启动,接着通知ApplicationThread启动目标Activity
  5. ActivityThread收到通知,执行Activity的创建、初始化操作。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/750599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不同语言采集【淘宝1688拼多多API】平台数据的方式

首先我们以taobao商品页面采集商品详情数据为例&#xff1a; 请求方式&#xff1a;HTTPS POST GET 请求地址&#xff1a;API接口 请求参数 请求参数&#xff1a;num_iid669646899650&is_promotion1参数说明&#xff1a;num_iid:淘宝商品ID is_promotion:是否获取取促销…

Space Saving算法

用于大数据中统计元素数量最多的元素的算法。 SpaceSaving算法是一种近似计数算法&#xff0c;它在大多数情况下能够提供准确的结果。然而&#xff0c;它并不是完全准确的&#xff0c;因为它使用了一些近似技巧来降低内存使用。具体来说&#xff0c;SpaceSaving算法通过牺牲一定…

基于STM32CUBEMX驱动TOF模块VL6180与VL6180X(4)----测量环境光

基于STM32CUBEMX驱动TOF模块VL6180与VL6180X----4.测量环境光 概述样品申请VL6180X传感器的测量流程ALS动态范围ALS动态范围测量流程光强计算公式配置vl6180x测试结果 概述 在本章中&#xff0c;我们将介绍如何配置VL6180X传感器以测量环境光&#xff0c;并获取环境光的强度值…

I.MX8MM系统构建 -- 2.linux内核编译烧录

准备源码 源码位置&#xff1a;/source/myir-imx-linux.tar.gz解压源码 tar zxf myir-imx-linux.tar.gz 编译 进入源码目录后&#xff0c;依次执行下列指令 myirmyir-server1:$ make distclean myirmyir-server1:$ make myd_imx8mm_defconfig myirmyir-server1:$ LDFLAG…

代码随想录刷题第53天|Leetcode1143最长公共子序列

1、Leetcode1143最长公共子序列 题目链接&#xff1a;1143最长公共子序列 本题不要求连续&#xff0c;求最长公共子序列。 1、确定dp数组及下标的含义 dp[i][j]&#xff1a;长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]。 2、…

volatile原理剖析和实例讲解

一、是什么 volatile是Java的一个关键字&#xff0c;是Java提供的一种轻量级的同步机制&#xff0c; 二、能做什么 保证了不同线程对这个变量进行操作时的可见性&#xff0c;有序性。 三、可见性 可见性主要是指一个线程修改了共享变量的值&#xff0c;另一个线程可以看见…

PreparedStatement 相比于 Statement的优点

PreparedStatement 相比于 Statement&#xff0c;有以下几个优点&#xff1a; 1. 预编译&#xff1a;PreparedStatement 对象在执行 SQL 语句之前会进行预编译&#xff0c;这意味着数据库管理系统可以提前解析和编译 SQL 语句&#xff0c;以优化执行计划&#xff0c;从而提高查…

【C语言初阶(15)】操作符1

文章目录 Ⅰ操作符的分类Ⅱ 算术操作符Ⅲ 移位操作符⒈左移操作符⒉右移操作符 Ⅳ 位操作符⒈按位取⒉按位与⒊按位异或⒋按位或⒌位操作符练习题 Ⅴ赋值操作符Ⅵ 单目操作符 Ⅰ操作符的分类 算术操作符移位操作符位操作符赋值操作符单目操作符关系操作符逻辑操作符条件操作符…

【ElasticSearch】ES集群搭建、监控、故障转移

文章目录 1、ES集群介绍2、搭建ES集群3、集群状态监控4、集群职责及脑裂5、分布式新增和查询流程6、ES故障转移 1、ES集群介绍 单机的ES做数据存储与搜索&#xff0c;必然面临两个问题&#xff1a; 海量数据存储问题单点故障问题 因此&#xff0c;考虑使用ES集群&#xff1a…

AIGC浪潮席卷,亚马逊云科技携手海尔设计、Nolibox加速工业设计转型

从机器学习算法到深度学习再到强化学习&#xff0c;AI创新浪潮奔流不息。而AIGC&#xff08;AI-generated Content&#xff0c;人工智能生成内容&#xff09;的到来&#xff0c;更是让AI成为众多企业的得力助手&#xff0c;开拓了文本、图像、音视频等领域的天花板。 在洞悉到…

x86架构ubuntu18下运行mgba模拟器

0. 环境 i7 ubuntu18 1. 准备源码 到https://github.com/mgba-emu/mgba/releases下载源码 mgba-0.10.2.tar.gz tar -zvxf mgba-0.10.2.tar.gz cd mgba0.10.2 2. 编译 mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX/home/xxjianvm/work/mgba-0.10.2/install .. make -j…

PROFINET转TCP/IP网关TCP/IP协议的含义是

大家好&#xff0c;今天要和大家分享一款自主研发的通讯网关&#xff0c;远创智控YC-PN-TCPIP。这款网关可是集多种功能于一身&#xff0c;PROFINET从站功能&#xff0c;让它在通讯领域独领风骚。想知道这款网关如何实现PROFINET和TCP/IP网络的连接吗&#xff1f;一起来看看吧&…

【GeoDa实用技巧100例】004:绘制长沙市宾馆热度图

文章目录 一、加载宾馆分布数据二、绘制热度图三、加载范围数据四、加载底图数据 一、加载宾馆分布数据 加载专栏配套的案例数据data004.rar中的长沙市宾馆酒店.shp&#xff0c;如下图&#xff0c;选择Shapefile格式&#xff1a; 选择长沙市宾馆酒店&#xff0c;加载如下&…

完全平方数(力扣)动态规划 JAVA

给你一个整数 n &#xff0c;返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数&#xff0c;其值等于另一个整数的平方&#xff1b;换句话说&#xff0c;其值等于一个整数自乘的积。例如&#xff0c;1、4、9 和 16 都是完全平方数&#xff0c;而 3 和 11 不是。 示…

【指针进阶】(题目练习)

这篇文章的思维导图在这里&#xff1a;思维导图 一维数组&#xff1a; int a[] {1,2,3,4}; printf("%d\n",sizeof(a)); printf("%d\n",sizeof(a0)); printf("%d\n",sizeof(*a)); printf("%d\n",sizeof(a1)); printf("%d\n"…

Vit 实战营 Class2:图像与Transformer基础

文章目录 数组图像&#xff1a;图像与像素图像分类&#xff1a;机器如何学习&#xff1f;NMT&#xff1a;Neuron Machine TranslationTransformerVision Transformer代码实战 数组图像&#xff1a;图像与像素 什么是数字图像&#xff1f;在计算机图像的图像格式。每一个点叫pix…

全国节能宣传周丨物通博联智慧能源解决方案助力节能降碳

今年7月10日至16日&#xff0c;为全国第33个节能宣传周。今年全国节能宣传周活动主题是“节能降碳&#xff0c;你我同行”。 全国节能宣传周活动是在1990年国务院第六次节能办公会议上确定的活动周&#xff0c;开展该活动是实施全面节约战略、开展节能降碳宣传教育、推动形成绿…

ros系统生成kinova双臂机器人moveit配置包方法,详细过程,亲测有效!

环境&#xff1a;ubuntu18.04 ros&#xff1a;melodic 此博客前提你已经安装了moveit&#xff0c;如果未安装&#xff0c;可参考链接 一、启动MoveIt Setup Assistant roslaunch moveit_setup_assistant setup_assistant.launch点击&#xff1a;Create New MoveIt Configurat…

听产品大佬谈大语言模型的商业化价值

今年 3 月以来&#xff0c;全球各大厂商陆续发布大语言模型&#xff0c;无数人欢欣鼓舞&#xff0c;庆祝沉寂了几年的 AI 领域重新焕发生机。 然而热闹过后&#xff0c;一个现实的问题摆在面前&#xff1a;大语言模型的商业化价值该如何挖掘&#xff1f; 来自美洽的资深产品经…

CVE-2021-41773

CVE-2021-41773 Apache Httpd Server 路径穿越漏洞 Httpd&#xff08;即 HTTP Daemon &#xff0c;超文本传输协议守护程序的简称&#xff09;是一款运行于网页服务器后台&#xff0c;等待传入服务器请求的软件。HTTP 守护程序能自动回应服务器请求&#xff0c;并使用 HTTP 协…