==

上文Android系统启动概述分析了系统的启动,而启动的最后一步则是启动Launcher

什么是Launcher

Android 12应用启动图标去掉_android


如果你不知道什么Launcher的话,看到上面的页面应该就知道了,Launcher其实就是桌面。

桌面上的图标则是启动器,我们可以通过这些图标启动对应的应用程序。

Launcher的启动

因为各版本差别比较大,所以分开几个版本分析,不想看源码的同学可以直接滑文末看总结

Android 8,9

先过下整体时序图:

Android 12应用启动图标去掉_android_02


上文中我们知道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

时序图:

Android 12应用启动图标去掉_java_03

与安卓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);
 }