Android启动过程简析(四)之Lanucher的启动

前言

通过Android启动过程简析(三)这篇文章我们已经大致了解了服务是如何被启动的,接着本文将会分析系统启动的最后一步,即 Launcher 的启动。

Lanucher的启动流程

在 SystemServer 中启动的这么多服务当中 ActivityManagerService 是负责四大组件的启动、切换、调度的,所以 Launcher 的启动与 ActivityManagerService 离不开关系

frameworks/base/services/java/com/android/server/SystemServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void startOtherServices() {
....

// 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() {
....
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
...
});
}

可以看到在 startOtherServices 中调用了 mActivityManagerService 的 systemReady 方法,并在传入的 Runnable 对象中启动了 SystemUi,接着继续查看 systemReady 方法

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
//第一次为false不会进入
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;
}

....
mSystemReady = true;
}

...

synchronized(this) {
// Make sure we have no pre-ready processes sitting around.

if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
....
}
}

...
//执行传入的Runnable对象
if (goingCallback != null) goingCallback.run();

...

synchronized (this) {
// Only start up encryption-aware persistent apps; once user is
// unlocked we'll come back around and start unaware apps
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);

// Start up initial activity.
mBooting = true;
// Enable home activity for system user, so that the system can always boot
...
//启动Lanucher的主Activity
startHomeActivityLocked(currentUserId, "systemReady");

...
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
}
}

在 systemReady 方法中会调用 startHomeActivityLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
}
//构建启动Lanucher主Activity的Intent对象
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);
//启动Lanucher主Activity
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}

return true;
}

进入 startHomeActivityLocked 方法之后可以看到调用了 getHomeIntent 返回了一个 Intent,我们都知道启动一个 Activity 的信息都是通过 Intent 进行传递的,所以继续查看 getHomeIntent 看看 Intent 包含的信息

1
2
3
4
5
6
7
8
9
10
Intent getHomeIntent() {
//mTopAction 是 android.intent.action.MAIN
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;
}

在 getHomeIntent 中首先创建了一个 Intent 对象,然后给这个对象增加了一个 category,category 对应的信息是 android.intent.category.HOME,查找 Lanucher3 的 AndroidManifest.xml 可以看见

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<activity
android:name="com.android.launcher3.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:theme="@style/Theme"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="nosensor"
android:configChanges="keyboard|keyboardHidden|navigation"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>

这说明即将启动的 Activity 是 com.android.launcher3.Launcher,现在回到 startHomeActivityLocked 方法中,继续往下看可以知道在得到 Intent 对象之后,最后是通过 ActivityStarter 的 startHomeActivityLocked 启动了 Launcher。之后的部分由于涉及到 Lanucher 源码和 Activity 启动的细致流程,所以就暂时不做分析了。

总结

通过四篇文章的分析对系统启动的过程有了一个大致的了解,但是限于水平有限,有些部分分析的比较粗糙,希望之后在水平提升之后能够对各个部分进行进一步的完善,例如:Binder、ActivityManagerService、Acitvity 的启动过程等等。 最后借用 Gityuan Android系统开篇中的一张图片说明系统启动的过程

Thanks

  1. Android系统启动流程(四)Launcher启动过程与系统启动流程