今天有空研究了一下系统启动流程中的Launcher启动时机,有必要给大家分享一下阅读代码的成果;
首先我们知道系统启动先会生成init进程,init进程会去启动各种守护进程类似usbd,adbd等,同时将启动Zygote进程,而之后Zygote进程会去起SystemServer进程,这个SystemServer是启动大部分服务的进程,同时将这些服务注册到ServiceManager中,其实应该能想到服务启动完之后就会去启动SystemUI和Launcher,于是进入SystemServer.java看一下:
System.loadLibrary("android_servers");
nativeInit();
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
以上代码可以看到,会先去启动启动引导服务,然后去启动核心服务,其实这两类服务都是去启动平台服务,接下去去启动其他服务,其他服务就是硬件服务,继续看代码startOtherServices
final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
final TextServicesManagerService textServiceManagerServiceF = tsms;
final StatusBarManagerService statusBarF = statusBar;
final AssetAtlasService atlasF = atlas;
final InputManagerService inputManagerF = inputManager;
final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
final MediaRouterService mediaRouterF = mediaRouter;
final AudioService audioServiceF = audioService;
final MmsServiceBroker mmsServiceF = mmsService;
// 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(new Runnable() {
@Override
public void run() {
Slog.i(TAG, "Making services ready");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
Slog.i(TAG, "WebViewFactory preparation");
WebViewFactory.prepareWebViewInSystemServer();
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
try {
if (mountServiceF != null) mountServiceF.systemReady();
} catch (Throwable e) {
reportWtf("making Mount Service ready", e);
}
上面代码中可以看到startSystemUi这个函数,很明显是去启动SystemUI了,启动Launcher代码应该也是差不多这个地方了,继续看方法mActivityManagerService.systemReady
int i;
for (i=0; i
我们看到startHomeActivityLocked这个方法,
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
Intent intent = getHomeIntent();
ActivityInfo aInfo =
resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
}
}
return true;
}
继续看getHomeIntent方法
UsageEvents.Event.MOVE_TO_BACKGROUND);
}
synchronized (stats) {
stats.noteActivityPausedLocked(component.app.uid);
}
}
}
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
这里我想大家就能看明白,其实getHomeIntent方法是去配置启动Launcher所需要的Intent,mStackSupervisor.startHomeActivity就是去启动Launcher应用的,StackSupervisor本质就是远端也就是服务端启动Activity的一个类,之前有分析过Activity启动流程,如果对Activity启动流程不是很熟的同学可以去了解一下。