Launcher概述
Launcher程序是我们平时看到的桌面程序,它其实也是一个Android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序,Android系统启动最后一步就是启动Launcher程序,应用程序Launcher在启动过程中会请求PackagerManagerService返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷键图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标icon启动相应的应用程序。
Launcher启动流程
SystemServer进程的启动过程中会调用main静态方法,开始执行整个SystemServer的启动流程,在其中通过调用三个内部boot/core/other [Service] 在调用startOtherService方法中就会通过调用mActivityManagerService.systemReady()方法,而这个ActivityManagerService的systemReady函数就是启动Launcher的入口。
在SystemServer所有的服务启动完毕之后,在startOtherServices的最后面就开始启动startSystemUi
#startOtherServices()
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
t.traceBegin("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
....
}, t)
可以发现这个方法传递了一个 Runnable参数,里面执行了各种其他服务的systemReady方法,这里不是我们关注的重点,继续看一下在ActivityManagerService中systemReady方法的具体实现
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback) {
...
// Start up initial activity.
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
...
}
重点是在这个方法中调用了 startHomeActivityLocked方法,看其名字就是开始执行启动HomeActivity操作
//启动主屏幕活动:为指定用户启动主屏幕应用 参数:userId - 目标用户ID,reason - 启动原因
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL&& mTopAction == null) {
//1 工厂测试检查,检查是否处于低级工厂测试模式且没有顶级动作
return false;
}
Intent intent = getHomeIntent();
//2 获取和解析主屏幕Intent
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
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) {
//3 启动主屏幕
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
mFactoryTest:代表系统运行模式,系统运行模式分为三种,分别是:
- 非工厂模式
- 低级工厂模式
- 高级工厂模式
mTopActivity:描述第一个被启动的Activity组件的Action,它的值为:Intent.ACTION_MAIN ;
所以FactoryTest.FACTORY_TEST_LOW_LEVEL(低级工厂模式)并且mTopAction=null时 直接返回为 false, 执行getHomeIntent()方法
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;
}
getHomeIntent函数中创建了Intent,并将mTopAction和mTopData传入。
mTopAction的值为:Intent.ACTION_MAIN,并且如果系统运行模式不是低级工厂模式,则将Intent的Category设置为:Intent.CATEGORY_HOME。Launcher的Intent对象中添加了Intent.CATEGORY_HOME常量,这个其实是一个launcher的标志,一般系统的启动页面Activity都会在androimanifest.xml中配置这个标志。
在ActivityManagerService的starHomeActivityLocked函数,假设系统运行的模式不是低级工厂模式,判断符合Action为:Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME的应用程序是否已经启动,如果没启动则启动该应用程序。
创建完Launcher所需的Inten后,就判断如果Launcher没有启动的话,就会去调用 mActivityStarter.startHomeActivityLocked()去启动Launcher
//frmework/base/services/core/java/com/android/server/am/ActivityStarter.java
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
//讲Launcher放入HomeStack中
mSupervisor.moveHomeStackTaskToTop(reason);
//启动Launcher
mLastHomeActivityStartResult = startActivityLocked();
}
在startHomeActivityLocked()里面,先把Launcher放入HomeStack中,HomeStack是在ActivityStackSupervisor中定义的,用来存储Launcher的变量,接着调用startActivityLocked()方法来启动Launcher。
到此,进入到Launcher的onCreate方法,Launcher启动完成。
....
调用startActivityLocked()方法后面的,就涉及到Activity启动流程。
核心启动时序
- 系统服务启动 → SystemServer 启动AMS、PMS
- 服务就绪 → ActivityManagerService.systemReady()
- HOME启动 → startHomeActivityLocked()
- Intent解析 → PackageManager 查找HOME应用
- 进程创建 → 启动Launcher进程
- UI初始化 → Launcher.onCreate()
关键方法调用链
- ActivityManagerService.systemReady()
- ActivityManagerService.startHomeActivityLocked()
- ActivityStarter.startActivity()
- PackageManagerService.queryIntentActivities()
- ActivityManagerService.startProcessLocked()
- Launcher.onCreate()