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,后续如果还有兴趣的话再补充.
Android系统启动流程-ART虚拟机的启动Android通知的简单用法
姜康
姜康
一个软件工程师
公告
type
status
date
slug
summary
tags
category
icon
password
🎉博客网站重新制作了🎉
👏欢迎更新体验👏