前言
根据前几篇文章,我们学习了Android系统启动流程相关的init进程、Zygote进程、SystemServer进程,这篇文章我们将来学习Launcher启动过程。
我们的android系统启动后,最终会显示在桌面界面,这个桌面就是我们今天要讲的Launcher,它也是一个应用程序。Launcher启动后,它会去找PKMS拿系统里已经安装过的应用程序信息,然后把这些应用程序的快捷图标一个个显示在系统屏幕上,这样我们就可以通过点击这些快捷图标来启动对应的应用。
Launcher启动过程介绍
在上一篇文章中提到过,在SystemServer里的run()方法中,会去调用startOtherServices()方法,去启动一些系统服务,在startOtherServices()方法里,我们可以看到调用到了AMS的systemReady()方法,记住这个方法,启动Launcher的入口,就是从这个方法开始的:
java
//代码文件位置:frmework/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
*****省略部分代码*****
//记住这个systemReady()
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY);
*****省略部分代码*****
}
下面来查看下AMS的systemReady()方法做了什么:
java
//代码文件位置:frmework/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
*****省略部分代码*****
mStackSupervisor.resumeFocusedStackTopActivityLocked();
*****省略部分代码*****
}
systemReady方法里,调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法:
java
//代码文件位置:frmework/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
*****省略部分代码*****
}
接着调用了ActivityStack的resumeTopActivityUncheckedLocked方法,ActivityStack对象是用来描述Activity堆栈的,resumeTopActivityUncheckedLocked方法源码如下:
java
//代码文件位置:frmework/base/services/core/java/com/android/server/am/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
result = resumeTopActivityInnerLocked(prev, options);
*****省略部分代码*****
}
接着看resumeTopActivityInnerLocked():
java
//代码文件位置:frmework/base/services/core/java/com/android/server/am/ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
*****省略部分代码*****
return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(prev, "prevFinished");
*****省略部分代码*****
}
resumeTopActivityInnerLocked()里的代码非常多,我们只分析最关键的一部分,调用了mStackSupervisor的resumeHomeStackTask方法,mStackSupervisor是一个ActivityStackSupervisor对象:
java
//代码文件位置:frmework/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
*****省略部分代码*****
return mService.startHomeActivityLocked(mCurrentUser, myReason);
}
这里的mService指的是AMS,可以看到在这里调用了AMS的startHomeActivityLocked方法:
java
//代码文件位置:frmework/base/services/core/java/com/android/server/am/ActivityManagerService.java
boolean startHomeActivityLocked(int userId, String reason) {
*****省略部分代码*****
//在这里创建 Launcher启动所需的Intent
Intent intent = getHomeIntent();
*****省略部分代码*****
//如果Launcher还没被创建的话
if (app == null || app.instr == null) {
//在这里 启动Launcher
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
}
}
首先会去调用getHomeIntent()方法,去创建Launcher启动所需的Intent,其中包括action设置为Intent.ACTION_MAIN,以及intent的Category设置为Intent.CATEGORY_HOME。
这里为什么要设置Intent.ACTION_MAIN和Intent.CATEGORY_HOME,其实我们可以去看Launcher的源码里,在它的AndroidManifest文件中,intent-filter标签就匹配了Action为Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME,这样我们这个Launcher应用就可正常被找到并启动啦
创建完Launcher所需的Intent后,就判断如果Launcher没有启动的话,就会去调用mActivityStarter.startHomeActivityLocked()去启动Launcher:
java
//代码文件位置:frmework/base/services/core/java/com/android/server/am/ActivityStarter.java
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
//讲Launcher放入HomeStack中
mSupervisor.moveHomeStackTaskToTop(reason);
mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent, null
/*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/, null /*voiceSession*/,
null /*voiceInteractor*/, null /*resultTo*/, null /*resultWho*/, 0 /*requestCode*/, 0
/*callingPid*/, 0 /*callingUid*/, null /*callingPackage*/, 0 /*realCallingPid*/, 0
/*realCallingUid*/, 0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/, null
/*container*/, null /*inTask*/, "startHomeActivity: " + reason);
}
在startHomeActivityLocked()里,先把Launcher放入HomeStack中,HomeStack是在ActivityStackSupervisor中定义的,用来存储Launcher的变量,接着调用startActivityLocked()方法来启动Launcher。
调用startActivityLocked()方法后面的源码,就涉及到Activity的启动流程了,我们后面会讲。
到此,最终就进入到Launcher的onCreate方法,Launcher启动完成。
时序图

系列文章
简单易懂系列文章
有所收获的朋友,请多多关注、点赞,谢谢大家!