Android之Launcher介绍(一)
目录
Android之zygote源码剖析(一)
Android之zygote源码剖析(二)
Android之zygote源码剖析(三)
Android之SystemServer介绍(一)
Android之SystemServer介绍(二)
Android之Launcher介绍(一)
Android之Launcher介绍(二)
Launcher启动
在SystemServer类中会调用startOtherServices函数:
private void startOtherServices() {
……
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
traceEnd();
traceBeginAndSlog("StartObservingNativeCrashes");
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
……
}, BOOT_TIMINGS_TRACE_LOG);
}
其中启动了很多的服务,主要关注下执行的mActivityManagerService.systemReady()
,其中
mActivityManagerService是ActivityManagerService服务。
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
这个写法是java的Lambda表达式。
进入systemReady(ActivityManagerService.java
)看一下:
public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
traceLog.traceBegin("PhaseActivityManagerReady");
……
synchronized (this) {
……
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
……
}
}
resumeFocusedStackTopActivityLocked函数位于ActivityStackSupervisor.java
中,ActivityStackSupervisor.java
类主要用来管理ActivityStack的:
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
函数中只要执行了ActivityStack.java
中的resumeTopActivityUncheckedLocked函数:
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
……
boolean result = false;
try {
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
mStackSupervisor.checkReadyForSleepLocked();
return result;
}
其中又调用了ActivityStack.java的resumeTopActivityInnerLocked函数:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
……
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(prev, "prevFinished");
……
}
其中又回调到ActivityStackSupervisor.java
的resumeHomeStackTask函数:
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
}
if (prev != null) {
prev.getTask().setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
}
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);
}
函数最后会调用mService的startHomeActivityLocked函数。
这个mService就是ActivityManagerService自身。
继续来看下startHomeActivityLocked函数:
boolean startHomeActivityLocked(int userId, String reason) {
// 判断是否是工厂模式和mTopAction是否存在
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
return false;
}
// 获取home intent(launcher)
Intent intent = getHomeIntent();
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);
// 如果当前launcher还没有启动就开始启动
if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
// 启动launcher
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
getHomeIntent函数如下:
Intent getHomeIntent() {
// 根据传入的mTopAction数据生成intent
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) {
// 添加匹配为CATEGORY_HOME
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
最终确定是启动Launcher是通过Intent.CATEGORY_HOME来匹配的。
AndroidManifest.xml文件中定义:
<activity
android:name="com.android.launcher3.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan|stateUnchanged"
android:screenOrientation="nosensor"
android:configChanges="keyboard|keyboardHidden|navigation"
android:resizeableActivity="true"
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>
其中的android.intent.category.HOME和上面的代码相互对应。
这样就启动了Launcher了。_
image.png