Android系统中Launcher的启动流程分析
Android中的Launcher就是Android系统的桌面,用于启动应用程序;作为Android的系统桌面,用于显示和管理应用程序的快捷图标或者其它桌面组件。
1.应用程序加载
在SystemServer进程启动的过程中会把PackageManagerServer启动,PackageManagerServer启动后会将系统中的应用程序安装完成;ActivityManagerServer(简称:AMS)是在PackageManagerServer之前启动的,当PackageManagerServer把应用程序安装完成后;AMS会把Launcher应用程序调起来。SystemServer中AMS与PMS的启动顺序:
private void startBootstrapServices() {
Installer installer = mSystemServiceManager.startService(Installer.class);
// Activity manager runs the show.
//这是AMS启动
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
//电源管理服务在这是启动
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Now that the power manager has been started, let the activity manager
// initialize power management features.
mActivityManagerService.initPowerManagement();
// Manages LEDs and display backlight so we need it to bring up the display.
mSystemServiceManager.startService(LightsService.class);
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// We need the default display before we can initialize the package manager.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// Start the package manager.
//PMS在这里启动起来
Slog.i(TAG, "Package Manager");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
Slog.i(TAG, "User Service");
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
// Initialize attribute cache used to cache resources from packages.
AttributeCache.init(mSystemContext);
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
startSensorService();
}
以上就是AMS和PMS的启动顺序,首先是AMS启动然后PMS再启动。
系统原码目录在:frameworks/base/services/java/com/android/server/SystemServer.java中可以看上述源码。
2.Launcher启动
启动Launcher入口在AMS的systemReady方法中,而调用这个方法的还是SystemServer,在SystemServer的startOtherServices中调用了AMS中的systemReady方法让Launcher启动;由于SystemServer的startOtherServices方法代码行数太多,这里给出调用AMS的中的systemReady方法部分源码:
private void startOtherServices() {
.................
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
Slog.i(TAG, "Making services ready");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
....................
}
....................
}
接下来到AMS中的systemReady方法中看Launcher是如何启动的,在Android8.0的部分代码中引入了Java的Lambad表达式,systemReady具体干了什么:
public void systemReady(final Runnble goingCallbac){
.....
synchronized(this){
....
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1,currentUserId);
}
}
systemReady方法中调用了ActivityStatckSupervisor中的resumeFocusedStackTopActivityLocked的方法,方法具体如下:
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!readyToResume()) {
return false;
}
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
其中ActivityStack 是用来描述Activity的堆栈信息的,resumeTopActivityUncheckedLocked具体又干了什么事情,代码如下:
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);
// When resuming the top activity, it may be necessary to pause the top activity (for
// example, returning to the lock screen. We suppress the normal pause logic in
// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
// end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
// to ensure any necessary pause logic occurs. In the case where the Activity will be
// shown regardless of the lock screen, the call to
// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
resumeTopActivityUncheckedLocked中主要调用了resumeTopActivityInnerLocked方法,由于该方法的代码比较多这里只给出关键的代码
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
....
if (!hasRunningActivity) {
// There are no activities left in the stack, let's look somewhere else.
return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
}
.....
}
这里面又调用了resumeTopActivityInNextFocusableStack方法
private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
ActivityOptions options, String reason) {
if (adjustFocusToNextFocusableStack(reason)) {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen or is on a secondary display (with no home
// stack).
return mStackSupervisor.resumeFocusedStackTopActivityLocked(
mStackSupervisor.getFocusedStack(), prev, null);
}
// Let's just start up the Launcher...
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityInNextFocusableStack: " + reason + ", go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on home display
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(prev, reason);
}
从上面又可以看到又调用了ActivityStackSupervisor中的resumeHomeStackTask方法
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
}
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);
}
在resumeHomeStackTask中可以看到最终看到调用了mService的startHomeActivityLocked方法来启动Launcher而这个mService就是ActivityManagerService(AMS)。
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();//创建 Launcher启动所需要的Intent
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() | 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;
mActivityStartController.startHomeActivity(intent, aInfo, myReason);//启动Launcher的Activity
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
接下来看一下getHomeIntent方法是怎么构建Launcher的Intent的
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;
}
最后看到Launcher的启动调用了 mActivityStartController.startHomeActivity方法,该方法如下:
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
mSupervisor.moveHomeStackTaskToTop(reason);//1
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
if (mSupervisor.inResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
// again. We need to schedule another resume.
mSupervisor.scheduleResumeTopActivities();
}
}
这里注释1中将Launcher放入到HomeStack中,HomStack是在ActivityStackSupervisor中定义的用来存储Launcher的变量。接下来就是启动Launcher的Activity了,Activity的启动过程下次有机会再分享;到这里Launcher的启动完成了。接下来附上Launcher启动的流程图
Launcher启动流程图.png
到这里Launcher的启动流程就分享到这里了;如果觉得该文章你有get到干货请给作者点个赞吧!