type
status
date
slug
summary
tags
category
icon
password
在SystemServer启动“Other”类型服务的时候,最后阶段会执行ActivityManagerService的
systemReady()
方法,这里就是启动桌面程序的入口.mActivityManagerService.systemReady(() -> { traceBeginAndSlog("StartSystemUI"); try { startSystemUi(context, windowManagerF); } catch (Throwable e) { reportWtf("starting System UI", e); } traceEnd(); // Wait for all packages to be prepared mPackageManagerService.waitForAppDataPrepared(); // It is now okay to let the various system services start their // third party code... traceBeginAndSlog("PhaseThirdPartyAppsCanStart"); mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); traceEnd(); }, BOOT_TIMINGS_TRACE_LOG);
在
ActivityManagerService
中的systemReady()方法中有这么一段:mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
在
ActivityTaskManagerService
中有实现:@Override public boolean startHomeOnAllDisplays(int userId, String reason) { synchronized (mGlobalLock) { return mRootActivityContainer.startHomeOnAllDisplays(userId, reason); } }
最终会执行到
RootActivityContainer
中:boolean startHomeOnAllDisplays(int userId, String reason) { boolean homeStarted = false; for (int i = mActivityDisplays.size() - 1; i >= 0; i--) { final int displayId = mActivityDisplays.get(i).mDisplayId; homeStarted |= startHomeOnDisplay(userId, reason, displayId); } return homeStarted; } 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) { // 获取Home Intent 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; }
这里会找到桌面程序的Intent:
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; }
剩下的就是启动桌面程序了.
Launcher的启动流程代码写的不是一般的混乱,启动Launcher的时候会有好几次的防护,针对Launcher启动崩溃也做了相应的处理.没有经过debug,可能存在其他的路径启动Launcher,后续如果还有兴趣的话再补充.
- 作者:姜康
- 链接:https://jiangkang.tech/article/267e1888-af3a-4c50-aa6a-7370d7c41df0
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章