在前面SystemUI启动流程中说到,在SystemServer中会去启动各种系统服务,这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前,系统四大组件的启动都是在ActivityManagerService中,在android10中,单独抽出了一个ActivityTaskManagerService,主要负责Activity的管理和调度。这里先来看下ActivityManagerService服务的启动:
// SystemServer.java private void startBootstrapServices() { ... ... // Activity manager runs the show. traceBeginAndSlog("StartActivityManager"); // TODO: Might need to move after migration to WM. ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); traceEnd(); ... ... }
当SystemServiceManager调用 startService() 时,就会通过反射去创建传进去的class,然后在调用创建对象的 onStart() 方法,这里就是去初始化ActivityTaskManagerService和ActivityManagerService对象,并不会去启动launcher,而且系统服务启动分为三块:
// SystemServer.java startBootstrapServices(); // 启动引导服务 startCoreServices(); // 启动核心服务 startOtherServices(); // 启动其他服务
在startOtherServices()中可以看到:
// SystemServer.java private void startOtherServices() { ... ... // We now tell the activity manager it is okay to run third party // code. It will call back into us once it has gotten to the state // where third party code can really run (but before it has actually // started launching the initial applications), for us to complete our // initialization. mActivityManagerService.systemReady(() -> { ... ... }); }
这就说明在所有服务初始化完成后,在这里会通知ActivityManagerService的systemReady()启动 launcher 的进程。
下面一起来看 launcher 是如何被启动起来的:
// ActivityManagerService.java public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ... ... mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); ... ... mAtmInternal.resumeTopActivities(false /* scheduleIdle */); ... ... }
mAtmInternal类型是ActivityTaskManagerInternal,这是一个抽象类,其实现是ActivityTaskManagerService的内部类LocalService:
// ActivityTaskManagerService.java final class LocalService extends ActivityTaskManagerInternal { ... ... @Override public boolean startHomeOnAllDisplays(int userId, String reason) { synchronized (mGlobalLock) { return mRootActivityContainer.startHomeOnAllDisplays(userId, reason); } } ... ... @Override public void resumeTopActivities(boolean scheduleIdle){ synchronized (mGlobalLock){ mRootActivityContainer.resumeFocusedStacksTopActivities(); if(scheduleIdle){ mStackSupervisor.scheduleIdleLocked(); } } } ... ... }
这里的mRootActivityContainer类型是RootActivityContainer,按照文档上的说明,这是一个临时类,主要是将ActivityStackSupervisor.java中的一部分逻辑分离出来,在android11中,这个类就已经找不到了。替换成了RootWindowContainer,这里我们跟进 mRootActivityContainer.startHomeOnAllDisplays() 方法看,最终会调用到:startHomeOnDisplay() :
// RootActivityContainer.java boolean startHomeOnDisplay(int userId,String reason,int displayId,boolean allowInstrumenting,boolean fromHomeKey){ // Fallback to top focused display if the displayId is invalid. if(displayId==INVALID_DISPLAY){ displayId=getTopDisplayFocusedStack().mDisplayId; } Intent homeIntent=null; ActivityInfo aInfo=null; if(displayId==DEFAULT_DISPLAY){ //拿到需要启动launcher的intent,通过resolveHomeActivity解析出需要启动的Activity homeIntent=mService.getHomeIntent(); aInfo=resolveHomeActivity(userId,homeIntent); }else if(shouldPlaceSecondaryHomeOnDisplay(displayId)){ Pair<ActivityInfo, Intent> info=resolveSecondaryHomeActivity(userId,displayId); aInfo=info.first; homeIntent=info.second; } if(aInfo==null||homeIntent==null){ return false; } if(!canStartHomeOnDisplay(aInfo,displayId,allowInstrumenting)){ return false; } // Updates the home component of the intent. homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName,aInfo.name)); homeIntent.setFlags(homeIntent.getFlags()|FLAG_ACTIVITY_NEW_TASK); // Updates the extra information of the intent. if(fromHomeKey){ homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY,true); } // Update the reason for ANR debugging to verify if the user activity is the one that // actually launched. final String myReason=reason+":"+userId+":"+UserHandle.getUserId( aInfo.applicationInfo.uid)+":"+displayId; mService.getActivityStartController().startHomeActivity(homeIntent,aInfo,myReason, displayId); return true; }
这里可以分为两步看:
1、通过ActivityTaskManagerService的getHomeIntent()获取到需要启动的intent,在通过resolveHomeActivity()解析出需要启动Activity的信息,
2、mService.getActivityStartController()获取到的是ActivityStartController,这个类的主要作用是用于控制委派启动的Activity。
先来看下ActivityTaskManagerService的getHomeIntent() :
// ActivityTaskManagerService.java Intent getHomeIntent() { Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); intent.setComponent(mTopComponent); intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { intent.addCategory(Intent.CATEGORY_HOME); } return intent; }
注意看 intent.addCategory(Intent.CATEGORY_HOME) ,这个代表的就是要启动Activity的意图,通常来说,整个系统的只会有一个应用会在清单文件中配置CATEGORY_HOME,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪个作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用启动。(这个 CATEGORY_HOME 配置,说白了就只有 launcher 程序才会有)。
回到主线,接着看mService.getActivityStartController().startHomeActivity() :
// ActivityStartController.java void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, TaskDisplayArea taskDisplayArea) { final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); if (!ActivityRecord.isResolverActivity(aInfo.name)) { // The resolver activity shouldn't be put in home stack because when the foreground is // standard type activity, the resolver activity should be put on the top of current // foreground instead of bring home stack to front. options.setLaunchActivityType(ACTIVITY_TYPE_HOME); } final int displayId = taskDisplayArea.getDisplayId(); options.setLaunchDisplayId(displayId); options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken .toWindowContainerToken()); // The home activity will be started later, defer resuming to avoid unneccerary operations // (e.g. start home recursively) when creating home stack. mSupervisor.beginDeferResume(); final ActivityStack homeStack; try { // Make sure home stack exists on display area. homeStack = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP); } finally { mSupervisor.endDeferResume(); } mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason) .setOutActivity(tmpOutRecord) .setCallingUid(0) .setActivityInfo(aInfo) .setActivityOptions(options.toBundle()) .execute(); mLastHomeActivityStartRecord = tmpOutRecord[0]; if (homeStack.mInResumeTopActivity) { // If we are in resume section already, home activity will be initialized, but not // resumed (to avoid recursive resume) and will stay that way until something pokes it // again. We need to schedule another resume. mSupervisor.scheduleResumeTopActivities(); } } /** * @return A starter to configure and execute starting an activity. It is valid until after * {@link ActivityStarter#execute} is invoked. At that point, the starter should be * considered invalid and no longer modified or used. */ ActivityStarter obtainStarter(Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); }
这里主要是先获取一个ActivityStarter(主要用于启动Activity),然后把需要的参数设置进去,最后再调用它的ActivityStarter.execute()方法:
// ActivityStarter.java int execute() { try { ... ... final LaunchingState launchingState; synchronized (mService.mGlobalLock) { final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo); // 通过ActivityMetricsLogger.notifyActivityLaunching创建LaunchingState并记录创建Activity开始的时间 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching( mRequest.intent, caller); } ... ... // 执行启动请求 res = executeRequest(mRequest); ... ... // Notify ActivityMetricsLogger that the activity has launched. // ActivityMetricsLogger will then wait for the windows to be drawn and populate // WaitResult. // 通过ActivityMetricsLogger.notifyActivityLaunched记录Activity启动完成的时间 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res, mLastStartActivityRecord); // 同时将Request.waitResult添加到ActivityStackSupervisor的mWaitingActivityLaunched中,等待窗口绘制完成 return getExternalResult(mRequest.waitResult == null ? res : waitForResult(res, mLastStartActivityRecord)); } finally { onExecutionComplete(); } }
通过上面代码我们知道,启动是在 executeRequest() 方法里:
// ActivityStarter.java private int executeRequest(Request request) { ... ... //调用 startActivityUnchecked mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, restrictedBgActivity, intentGrants); return mLastStartActivityResult; }
ActivityStarter.startActivityUnchecked()
// ActivityStarter.java private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants) { int result = START_CANCELED; ... ... try { //延时布局 mService.deferWindowLayout(); //执行startActivityInner result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants); } finally { //恢复布局 mService.continueWindowLayout(); } ... ... return result; }
ActivityStarter.startActivityInner()
int startActivityInner() { ... ... if (mDoResume) { //ActivityRecord 记录着 Activity 信息 final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isTopActivityFocusable() || (topTaskActivity != null && topTaskActivity.isTaskOverlay() && mStartActivity != topTaskActivity)) { mTargetStack.getDisplay().mDisplayContent.executeAppTransition(); } else { //执行resumeFocusedStacksTopActivities mRootWindowContainer.resumeFocusedStacksTopActivities( mTargetStack, mStartActivity, mOptions); } } ... ... return START_SUCCESS; }
RootWindowContainer.resumeFocusedStacksTopActivities()
// RootWindowContainer.java boolean resumeFocusedStacksTopActivities( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { ... ... //如果是栈顶Activity,启动resumeTopActivityUncheckedLocked if (targetStack != null && (targetStack.isTopStackInDisplayArea() || getTopDisplayFocusedStack() == targetStack)) { result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } ... ... if (!resumedOnDisplay) { //获取栈顶的 ActivityRecord final ActivityStack focusedStack = display.getFocusedStack(); if (focusedStack != null) { //执行resumeTopActivityUncheckedLocked result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); }else if (targetStack == null) { result |= resumeHomeActivity(null /* prev */, "no-focusable-task", display.getDefaultTaskDisplayArea()); } } return result; }
ActivityStack.resumeTopActivityUncheckedLocked()
// ActivityStack.java boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { if (mInResumeTopActivity) { // Don't even start recursing. return false; } boolean result = false; try { mInResumeTopActivity = true; // 执行 resumeTopActivityInnerLocked, // 最终调用到 ActivityStackSupervisor.startSpecificActivity() result = resumeTopActivityInnerLocked(prev, options); final ActivityRecord next = topRunningActivity(true /* focusableOnly */); if (next == null || !next.canTurnScreenOn()) { checkReadyForSleep(); } } finally { mInResumeTopActivity = false; } return result; }
ActivityStackSupervisor.startSpecificActivity()
// ActivityStackSupervisor.java void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? final WindowProcessController wpc = mService.getProcessController(r.processName, r.info.applicationInfo.uid); boolean knownToBeDead = false; //进程存在 if (wpc != null && wpc.hasThread()) { try { //真正启动Activity方法 realStartActivityLocked(r, wpc, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } // If a dead object exception was thrown -- fall through to // restart the application. knownToBeDead = true; } r.notifyUnknownVisibilityLaunchedForKeyguardTransition(); final boolean isTop = andResume && r.isTopRunningActivity(); //进程不存在 mService =ATMS mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity"); }
startSpecificActivity() 这个方法是关键方法,如果进程已经存在直接执行 realStartActivityLocked 去启动 Activity,进程不存在则通过AMS去创建 Socket,然后通知 Zygote 去 fork 进程。由于这里第一次创建,所以会走到 startProcessAsync() 。
Launcher启动流程调用栈: