基于Android U
SystemServer进程在启动的过程中会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。先前已经启动的AMS会将Launcher启动起来。时序图如下:

启动Launcher的入口为AMS的systemReady()方法,它在SystemServer的startOtherServices()方法中被调用。
1 2 3 4 5 6 7 8 9 10 11 12
| /frameworks/base/services/java/com/android/server/SystemServer.java private void startOtherServices(@NonNull TimingsTraceAndSlog t) { ... mActivityManagerService.systemReady(() -> { Slog.i(TAG, "Making services ready"); t.traceBegin("StartActivityManagerReadyPhase"); mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY); t.traceEnd(); ... }, t); ... }
|
ActivityManagerService#systemReady
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) { ... synchronized (this) { ... boolean isBootingSystemUser = currentUserId == UserHandle.USER_SYSTEM; if (isBootingSystemUser && !UserManager.isHeadlessSystemUserMode()) { t.traceBegin("startHomeOnAllDisplays"); mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); t.traceEnd(); } ... } }
|
mAtmInternal.startHomeOnAllDisplays最终调用了RootWindowContainer.startHomeOnAllDisplays()。
1 2 3 4 5 6 7 8 9
| /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java boolean startHomeOnAllDisplays(int userId, String reason) { boolean homeStarted = false; for (int i = getChildCount() - 1; i >= 0; i--) { final int displayId = getChildAt(i).mDisplayId; homeStarted |= startHomeOnDisplay(userId, reason, displayId); } return homeStarted; }
|
在每个display上显示对应的Home界面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java boolean startHomeOnDisplay(int userId, String reason, int displayId) { return startHomeOnDisplay(userId, reason, displayId, false , false ); }
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey) { if (displayId == INVALID_DISPLAY) { final Task rootTask = getTopDisplayFocusedRootTask(); displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY; }
final DisplayContent display = getDisplayContent(displayId); return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea, allowInstrumenting, fromHomeKey), false ); }
|
调用startHomeOnTaskDisplayArea()启动每个显示区域(DisplayArea)的Home界面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting, boolean fromHomeKey) { ...
Intent homeIntent = null; ActivityInfo aInfo = null; if (taskDisplayArea == getDefaultTaskDisplayArea() || mWmService.shouldPlacePrimaryHomeOnDisplay( taskDisplayArea.getDisplayId(), userId)) { homeIntent = mService.getHomeIntent(); aInfo = resolveHomeActivity(userId, homeIntent); } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) { Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea); aInfo = info.first; homeIntent = info.second; } ... mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason, taskDisplayArea); return true; }
|
判断传入的TaskDisplayArea是否是默认的TaskDisplayArea。如果是,mService.getHomeIntent()获取对应的Intent,这就是传统的Launcher的启动意图。
在getHomeIntent()方法中创建了Intent,并将mTopAction和mTopData传入。mTopAction的值为Intent.ACTION_MAIN,并且如果系统运行模式不是低级工厂模式,则将Intent的Category设置为Intent.CATEGORY_HOME,最后返回该Intent。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| /frameworks/base/services/core/java/com/android/server/wm/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; }
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, TaskDisplayArea taskDisplayArea) { ... mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason) .setOutActivity(tmpOutRecord) .setCallingUid(0) .setActivityInfo(aInfo) .setActivityOptions(options.toBundle()) .execute(); ... }
|
startHomeActivity()启动的应用程序就是Launcher,因为Launcher的AndroidManifest.xml文件中的intent-filter标签匹配了Action为Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME。
execute()处理Activity启动请求的接口,executeRequest()执行一系列权限检查,对于合法的请求才继续。
1 2 3 4 5
| /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java int execute() { ... res = executeRequest(mRequest); }
|
后面的步骤和《根Activity的启动过程》相同。