Android开机启动流程的分析主要分为以下部分:
(01)init之前启动说明
(02)init的启动流程分析
(03)init启动中关键进程 uevent & watchdog
(04)init启动中关键服务-属性服务
(05)SE Android 的解读
(06)init.rc解析流程
(07)action队列分析
(08)无限循环的处理
(09)bootchart 解读
(10)init 部分整体总结 --总结性说明{关键:思维导图重构 & 流程说明}
(11)Zygote启动分析
(12)SystemServer启动分析
(13)Zygote的分裂
(14)SystemServer WatchDog解读
(15)SystemServer部分服务解读
(16)Launcher启动
本模块分享的内容:Launcher启动
这里因为整体的导图太大,因此截取一部分 ,方便大家看的清楚:
在上图中关注➕“launcher启动”部分即可。同时,下面的图是开机启动流程分析 持续迭代的效果,可放大观看。
在SystemServer启动后,SystemServer又启动了AMS,同时在SystemServer中关键方法 startOtherServices 中
private void startOtherServices() {
//...
final AudioService audioServiceF = audioService;
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 (mmsServiceF != null) mmsServiceF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying MmsService running", e);
}
}
});
1 这里专注AMS的SystemReady方法,实现如下:
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {
// If we're done calling all the receivers, run the next "boot phase" passed in
// by the SystemServer
if (goingCallback != null) {
goingCallback.run();
}
return;
}
//...
/**startHomeActivityLocked调用栈
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
moveHomeStackTaskToTop
startActivityLocked,这里接下来启动Activity的启动流程
*/
startHomeActivityLocked(mCurrentUserId, "systemReady");
//...
}
}
这里在startHomeActivityLocked之后 便开始 执行 Activity的启动流程了,因为这里涉及的函数调用层数比较多,这里整理了一下startHomeActivityLocked的调用栈,如下所示:
/**startHomeActivityLocked调用栈*/
ActivityStackSupervisor:
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
moveHomeStackTaskToTop->startActivityLocked,这里接下来启动Activity的启动流程
startActivityUncheckedLocked
resumeTopActivityLocked
-------------------------------------------------------
ActivityStack:->targetStack.startActivityLocked
mStackSupervisor.resumeTopActivitiesLocked
targetStack.resumeTopActivityLocked
resumeTopActivityInnerLocked
---------------------------------------
ActivityStackSupervisor:
mStackSupervisor.startSpecificActivityLocked
mService.getProcessRecordLocked
realStartActivityLocked
mService.startProcessLocked //创建 ActivityThread线程
在这里,最后 调用的 startProcessLocked方法,目的就是 创建ActivityThread线程
2 创建ActivityThread线程流程如下:
mService.startProcessLocked //创建 ActivityThread线程
Process.start
startViaZygote
zygoteSendArgsAndGetResult
3 最后在ActivityThread 启动后,执行main方法,分析如下:
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("");
//创建looper对象,与本线程绑定,在activity或service或dialog中可以随便使用handler是这个线程在后台
Looper.prepareMainLooper();
//创建ActicityThread对象实例,当new ActivityThread()进行时,其成员变量ApplicationThread同时被创建
ActivityThread thread = new ActivityThread();
/**进行attach回调,调用栈如下:
mgr.attachApplication(mAppThread);
这里走的是binder通信->call AMS:attachApplication->attachApplicationLocked
*/
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
4 这里最为关键的一个步骤是attach,这里详细分析下:
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
//...
app.makeActive(thread, mProcessStats);
//...
try {
//...
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// ...
return false;
}
//...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
//...
}
}
//...
return true;
}
这里代码做了大部分的删减,主要表明这里做了4件事情,分别是
通过attach,ActivityThread的ApplicationThread.scheduleResumeActivity触发显示,到此 Launcher 的Activity也就启动并显示出来了