==
上文Android系统启动概述分析了系统的启动,而启动的最后一步则是启动Launcher
什么是Launcher
如果你不知道什么Launcher的话,看到上面的页面应该就知道了,Launcher其实就是桌面。
桌面上的图标则是启动器,我们可以通过这些图标启动对应的应用程序。
Launcher的启动
因为各版本差别比较大,所以分开几个版本分析,不想看源码的同学可以直接滑文末看总结
Android 8,9
先过下整体时序图:
上文中我们知道Zygote进程启动了SystemServer进程, 而启动 Launcher的入口为AMS的systemReady方法, 在SystemServer的startOtherServices方法中被调用
如下所示:
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
private void run() {
…
// Start services.
try {
t.traceBegin(“StartServices”);
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
} catch (Throwable ex) {
Slog.e(“System”, “******************************");
Slog.e(“System”, " Failure starting system services”, ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
…
}private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
…
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, “Making services ready”);
t.traceBegin(“StartActivityManagerReadyPhase”);
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
…
}
…
}
}
看下systemReady的实现
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
…
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
traceLog.traceEnd(); // ActivityManagerStartApps
traceLog.traceEnd(); // PhaseActivityManagerReady
}
可知下面交给了ActivityStackSupervisor
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (!readyToResume()) {
return false;
}if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}…
return false;
}
后面则是调用ActivityStack的resumeTopActivityUncheckedLocked方法
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don’t even start recursing.
return false;
}boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
…
return result;
}private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
…
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(prev, “prevFinished”);
…
}
ActivityStack最终又调用了ActivityStackSupervisor的resumeHomeStackTask方法
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
…
mHomeStack.moveHomeStackTaskToTop();
ActivityRecord r = getHomeActivity();
final String myReason = reason + " resumeHomeStackTask";// Only resume home activity if isn’t finishing.
if (r != null && !r.finishing) {
moveFocusableActivityStackToFrontLocked(r, myReason);
return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
}
return mService.startHomeActivityLocked(mCurrentUser, myReason);
}
最后回到AMS,调用AMS的startHomeActivityLocked方法
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
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.instr == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
// For ANR debugging to verify if the user activity is the one that actually
// launched.
final String myReason = reason + “:” + userId + “:” + resolvedUserId;
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}return true;
}Intent getHomeIntent() {
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;
}
这里启动了一个Intent,可以通过源码看到Launcher的清单配置
packages/apps/Launcher3/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
最终使用ActivityStarter启动Launcher,后面的流程可参考Activity的启动
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
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 /inTask/, "startHomeActivity: " + reason);…
}
小结
- SystemServer中使用AMS启动Launcher
- AMS调用 ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法
- 经历了ActivityStackSupervisor -> ActivityStack -> ActivityStackSupervisor ->AMS 的流程,期间处理了一些堆栈相关的工作,最终又回到了AMS
- AMS调用 ActivityStarter启动Launcher Activity
建议看完源码,回头看下时序图,会比较清晰
Android 10
时序图:
与安卓8一样从AMS启动,不同的是安卓10交给了一个ActivityTaskManagerInternal类型的服务mAtmInternal
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@VisibleForTesting
public ActivityTaskManagerInternal mAtmInternal;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
…
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
…
t.traceBegin(“resumeTopActivities”);
mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
t.traceEnd();
…
}
我们看下mAtmInternal哪来的,LocalServices类里面是一个类与对象的键值对, 而ActivityTaskManagerInternal是一个抽象类,我们找到它的唯一继承类ActivityTaskManagerService.LocalService
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
RootActivityContainer mRootActivityContainer;
final class LocalService extends ActivityTaskManagerInternal {
@Override
public void resumeTopActivities(boolean scheduleIdle) {
synchronized (mGlobalLock) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
…
}
}
}
}
这里调用了RootActivityContainer的resumeFocusedStacksTopActivities方法
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeFocusedStacksTopActivities() {
return resumeFocusedStacksTopActivities(null, null, null);
}
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {…
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
…
if (!resumedOnDisplay) {final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}return result;
}
老环节,接下来又走到了ActivityStack
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
…
result = resumeTopActivityInnerLocked(prev, options);
…}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
…if (!hasRunningActivity) {
// There are no activities left in the stack, let’s look somewhere else.
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}
…
}private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
ActivityOptions options) {
…
return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
}resumeNextFocusableActivityWhenStackIsEmpty 方法又调用了RootActivityContainer的resumeHomeActivity
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
…
return startHomeOnDisplay(mCurrentUser, myReason, displayId);
}boolean startHomeOnDisplay(int userId, String reason, int displayId) {
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting /,
false / fromHomeKey */);
}startHomeOnDisplay里面取到了homeIntent,然后我们看最后一行:
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
…Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
aInfo = info.first;
homeIntent = info.second;
}
…// 启动HomeActivity mService 是ActivityTaskManagerService
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}mService.getActivityStartController()获取到的是ActivityStartController
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
private ActivityStartController mActivityStartController;
ActivityStartController getActivityStartController() {
return mActivityStartController;
}public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController,
Looper looper) {
…
mActivityStartController = new ActivityStartController(this);
…
}最后使用ActivityStartController来启动Launcher
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {
…mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
…
if (homeStack.mInResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}