Android系统启动(四) — Launcher 启动过程
系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做Launcher。Launcher在启动过程中会请求返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户就可以通过点击这些快捷图标来启动相应的应用程序。通俗的讲,Launcher就是Android系统的桌面,作为Android系统的启动器,用于启动应用程序;作为Andro
1 Launcher
概述
系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做 Launcher
。Launcher
在启动过程中会请求 PackageManagerService
返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户就可以通过点击这些快捷图标来启动相应的应用程序。
通俗的讲,Launcher
就是 Android
系统的桌面, 它的作用主要有以下两点:
- 作为
Android
系统的启动器,用于启动应用程序; - 作为
Android
系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件;
2 Launcher
启动过程
SystemServer
进程在启动的过程中会启动 PackageManagerService
,PackageManagerService
启动后会将系统中的应用程序安装完成,在此之前已经启动的 ActivityManagerService
会将 Launcher
启动起来。
Launcher
的启动分为三个部分:
SystemServer
完成启动Launcher
的Activity
的相关配置;Zygote
进程fork
出Launcher
进程;- 进入
ActivityThread.main
函数,最终完成Launcher
的Activity.onCreate
操作;
第一阶段 完成 Launcher
的相关配置
在 SystemServer.startOtherServices
方法中调用 ActivityManagerService.systemReady
方法,Launcher
进程的启动就是从这里开始的,以下是相关源码:
// /frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
...
mActivityManagerService.systemReady(() -> { // 1
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
traceEnd();
}
...
)
}
以下是 ActivityManagerService.systemReady
方法的源码:
// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public ActivityTaskManagerInternal mAtmInternal;
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
...
// 启动 Home Activity,即 Launcher 应用的入口 Activity,这里指的是,在所有屏幕上启动 Launcher。因为 Android 10 开始支持多屏幕,比如手机屏幕、虚拟投屏、外接屏幕
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); // 1
...
}
这里的 mAtmInternal
是 ActivityTaskManagerInternal
的实例,ActivityTaskManagerInternal
是一个抽象类。 ActivityManagerService
中的内部类 LocalService
实现了 ActivityTaskManagerInternal
:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {
...
@Override
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
}
}
...
}
在 LocalService.startHomeOnAllDisplays
方法中调用了 RootActivityContainer.startHomeOnAllDisplays
方法。RootActivityContainer
的作用是,调用 PackageManagerService
中去查询手机系统中已经安装的应用哪一个符合 Launcher
标准,且返回一个 Intent
对象,并且交给 ActivityStarter
:
// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
final int displayId = mActivityDisplays.get(i).mDisplayId;
homeStarted |= startHomeOnDisplay(userId, reason, displayId); // 1
}
return homeStarted;
}
boolean startHomeOnDisplay(int userId, String reason, int displayId) {
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,false /* fromHomeKey */);
}
boolean startHomeOnDisplay(int userId, String reason, int displayId,
boolean allowInstrumenting, boolean fromHomeKey) {
...
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
// 构建一个 category 为 CATEGORY_HOME 的 Intent,表明是 HomeActivity
homeIntent = mService.getHomeIntent(); // 2
// 通过 PMS 从系统所有已安装的引用中找到一个符合 homeIntent 的 Activity
aInfo = resolveHomeActivity(userId, homeIntent); // 3
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
...
}
...
// 启动 Launcher
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo,
myReason, displayId); // 4
return true;
}
在注释 2
处调用了 ActivityTaskManagerService.getHomeIntent()
方法来构建一个 category
为 CATEGORY_HOME
的 Intent
,表明是一个符合 Launcher
应用的 Intent
。在注释 3
处通过调用 resolveHomeActivity
方法解析出需要启动 Activity
的信息。在注释 4
处调用 ActivityTaskManagerService.getActivityStartController()
获取 ActivityStartController
,这个类的作用就是做启动前的各项检查,比如,Activity
是否有清单文件注册,Class
文件是否存在等,之后启动 Activity
。
以下是相关的时序图:
首先,看一下 ActivityTaskManagerService.getHomeIntent()
方法,主要是构建一个符合 Launcher
应用的 Intent
:
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
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); // 1
}
return intent;
}
在注释 1
处代表的是要启动 Activity
的意图,通常来说,整个系统只会有一个应用在清单文件中配置 CATEGORY_HOME
,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪一个应用作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用。
接着看 RootActivityContainer.resolveIntentInternal
方法:
// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
int flags, int userId,
boolean resolveForStart,
int filterCallingUid) {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
if (!sUserManager.exists(userId)) return null;
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final ResolveInfo bestChoice =
chooseBestActivity(intent, resolvedType, flags, query, userId);
return bestChoice;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
通过 Binder
跨进程通信通知 PackageManagerService
从系统所有已经安装的应用中找到一个符合 homeInent
的 Activity
。
再看 ActivityStartController.startHomeActivity
的代码:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
int displayId) {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (!ActivityRecord.isResolverActivity(aInfo.name)) {
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
options.setLaunchDisplayId(displayId);
mLastHomeActivityStartResult =
obtainStarter(intent, "startHomeActivity: " + reason) // 1
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute(); // 2
mLastHomeActivityStartRecord = tmpOutRecord[0];
final ActivityDisplay display =
mService.mRootActivityContainer.getActivityDisplay(displayId);
final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
if (homeStack != null && homeStack.mInResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}
ActivityStarter obtainStarter(Intent intent, String reason) { // 3
return mFactory.obtain().setIntent(intent).setReason(reason);
}
在注释 1
处先获取一个 ActivityStarter
,主要用于启动 Activity
,然后把需要的参数设置进去,最后再调用它的 execute()
方法:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
try {
if (mRequest.mayWait) {
...
} else {
return startActivity(...);
}
} finally {
onExecutionComplete();
}
}
以下是 ActivityStarter.startActivity
的相关源码,这个方法主要是用来做 Activity
启动之前的安全校验:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivity(...) {
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle
= options != null ? options.popAppVerificationBundle() : null;
WindowProcessController callerApp = null;
if (caller != null) {
callerApp = mService.getProcessController(caller);
if (callerApp != null) {
callingPid = callerApp.getPid();
callingUid = callerApp.mInfo.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
}
}
...
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true /* doResume */, checkedOptions,
inTask, outActivity, restrictedBgActivity);
...
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, ActivityOptions options,
TaskRecord inTask, ActivityRecord[] outActivity,
boolean restrictedBgActivity) {
...
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask,
outActivity, restrictedBgActivity); // 1
...
}
注释 1
处调用了 ActivityStarter.startActivityUnchecked
的代码:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r,
ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, ActivityOptions options,
TaskRecord inTask, ActivityRecord[] outActivity,
boolean restrictedBgActivity) {
...
final int preferredWindowingMode = mLaunchParams.mWindowingMode;
computeLaunchingTaskFlags(); // 1
computeSourceStack(); // 2
mIntent.setFlags(mLaunchFlags);
ActivityRecord reusedActivity = getReusableIntentActivity();
...
mRootActivityContainer.resumeFocusedStacksTopActivities(); // 3
...
}
注释 1
处的 ActivityStarter.computeLaunchingTaskFlags()
方法是根据 Activity
的 launcher mode
和 intent.flag
计算出 Activity
的入栈方式。注释 2
处的 ActivityStarter.computeSourceStack()
计算从哪个栈中启动该 Activity
。注释 3
处调用了 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) {
...
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
...
if (!resumedOnDisplay) {
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); // 1
}
}
}
return result;
}
在注释 1
处调用 ActivityStack.resumeTopActivityUncheckedLocked
方法:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
result = resumeTopActivityInnerLocked(prev, options);
...
}
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev,
ActivityOptions options) {
...
if (anim) {
next.applyOptionsLocked();
} else {
next.clearOptionsLocked();
}
mStackSupervisor.mNoAnimActivities.clear();
if (next.attachedToProcess()) { // 待启动的进程是否创建完成,如果没有就会到 else 中
...
} else {
mStackSupervisor.startSpecificActivityLocked(next, true, true); // 1
}
...
}
在注释 1
处调用 ActivityStackSupervisor.startSpecificActivityLocked
:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume,
boolean checkConfig) {
...
try {
...
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, // 1
mService.mAmInternal, r.processName, r.info.applicationInfo,
knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
注释 1
出调用的其实是 ActivityManagerService.startProcess
方法,开始创建进程:
// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class LocalService extends ActivityManagerInternal {
@Override
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType,
ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
startProcessLocked(processName, info, knownToBeDead,
0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */,
false /* isolated */,
true /* keepIfLarge */); // 1
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info,
boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord,
boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead,
intentFlags,
hostingRecord, allowWhileBooting,
isolated, 0 /* isolatedUid */,
keepIfLarge,
null /* ABI override */,
null /* entryPoint */,
null /* entryPointArgs */,
null /* crashHandler */); // 2
}
}
在注释 1
处调用 LocalService.startProcessLocked
方法。在 LocalService.startProcessLocked
方法中又把进程创建的工作委派给了 ProcessList
。接着看 ProcessList.startProcessLocked
方法:
// /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
startProcessLocked(app, hostingRecord, null /* abiOverride */);
}
@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
String abiOverride) {
return startProcessLocked(app, hostingRecord, false /* disableHiddenApiChecks */,
false /* mountExtStorageFull */, abiOverride);
}
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
boolean disableHiddenApiChecks,
boolean mountExtStorageFull,
String abiOverride) {
...
final String entryPoint = "android.app.ActivityThread"; // 1
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
}
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord,
boolean allowWhileBooting, boolean isolated,
int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint,
String[] entryPointArgs, Runnable crashHandler) {
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkSlow(startTime, "startProcess: after getProcessRecord");
...
}
final String entryPoint = "android.app.ActivityThread";
...
}
这几个方法的作用是在进程创建之前,配置一些必要的参数,比如版本号之类的参数。在注释 1
处是一个非常重要的参数,entryPoint
是新进程的入口。所以,Android
应用的程序入口是 ActivityThread
。
创建进程所需的参数配置完成后,最终会走到 ZygoteProcess
类中:
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
@Nullable final String niceName,
final int uid, final int gid,
@Nullable final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
boolean startChildZygote,
@Nullable String packageName,
boolean useUsapPool,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized (mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
useUsapPool, argsForZygote);
}
}
此时还处于 system_server
进程,这个类的目的是创建本地的 Socket
连接对象,连接到 Zygote
进程的 Socket
方法,然后通过字符输入流,把创建进程所需要的参数发送过去。
第二阶段:Zygote
进程接收请求并创建 Launcher
进程
参考 应用程序进程启动过程
第三个阶段:进入 ActivityThread.main
,最终完成 Launcher.onCreate
操作
Zygote
fork
出了 Launcher
进程,并把接下来的 Launcher
启动任务交给了 ActivityThread
来进行,接下来就从 ActivityThread.main
方法来分析 Launcher
的创建过程。 以下是 ActivityThread
启动 Activity
的时序图:
ActivityThread.main
方法是程序入口,以下是相关代码:
// /frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
...
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq); // 1
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在注释 1
处调用 ActivityThread.attach
方法,以下是相关源码:
// /frameworks/base/core/java/android/app/ActivityThread.java
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService(); // 1
try {
mgr.attachApplication(mAppThread, startSeq); // 2
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...
}
...
}
在注释 1
处获取 ActivityManagerService
的实例,在注释 2
处调用 ActivityManagerService.attachApplication
方法:
// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
// 通过 Binder 获取传入的 pid 信息
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq); // 1
Binder.restoreCallingIdentity(origId);
}
}
public ActivityTaskManagerInternal mAtmInternal;
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); // 2
...
}
在注释 1
处调用了 ActivityManagerService.attachApplicationLocked
方法。注释 2
处的 mAtmInternal
是 ActivityTaskManagerInternal
类型的变量, ActivityTaskManagerService
中的内部类 LocalService
继承自 ActivityTaskManagerInternal
,以下是相关源码:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc); // 1
}
}
}
在注释 1
处调用了 RootActivityContainer.attachApplication
方法:
// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
final ActivityStack stack = display.getFocusedStack();
if (stack != null) {
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
// 1
if (mStackSupervisor.realStartActivityLocked(activity, app,
top == activity /* andResume */,
true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisible(null, 0, false /* preserve_windows */);
}
return didSomething;
}
在注释 1
处调用 ActivityStackSupervisor.realStartActivityLocked
方法:
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor,
proc.getReportedProcState(), r.icicle, r.persistentState, results,
newIntents, dc.isNextTransitionForward(),
proc.createProfilerInfoIfNeeded(), r.assistToken)); // 1
...
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction); // 2
...
}
注释 2
处 ActivityTaskManagerService.getLifecycleManager
方法返回 ClientLifecycleManager
实例。以下是 ClientLifecycleManager.scheduleTransaction
的相关源码:
// /frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule(); // 1
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
在注释 1
处调用了 ClientTransaction.schedule
方法:
// /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this); // 1
}
注释 1
处的 mClient
是 IApplicationThread
实例,在这里是 ApplicationThread
,ApplicationThread
是 ActivityThread
的内部类,以下是相关源码:
// /frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction); // 1
}
}
注释 1
处调用了 ActivityThread.this.scheduleTransaction
方法,ActivityThread
继承自 ClientTransactionHandler
,因此这里调用的是 ClientTransactionHandler.scheduleTransaction
方法,以下是相关源码:
// /frameworks/base/core/java/android/app/ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); // 1
}
注释 1
处的 ActivityThread.H
是 Handler
的子类,以下是 ActivityThread.sendMessage
方法的源码和关于 ActivityThread.H.EXECUTE_TRANSACTION
的相关处理:
// /frameworks/base/core/java/android/app/ActivityThread.java
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) {
Slog.v(TAG,
"SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
}
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
class H extends Handler {
...
public static final int EXECUTE_TRANSACTION = 159;
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction); // 1
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
...
}
}
}
在注释 1
处调用了 TransactionExecutor.execute
方法
// /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction); // 1
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
...
item.execute(mTransactionHandler, token, mPendingActions); // 2
..
}
}
注释 2
处调用了 ClientTransactionItem.execute
方法,该方法在其子类 LaunchActivityItem
中实现,以下是 LaunchActivityItem.execute
方法:
// /frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java)
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer,
mVoiceInteractor, mState,
mPersistentState,
mPendingResults, mPendingNewIntents,
mIsForward,
mProfilerInfo, client, mAssistToken);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */); // 1
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
注释 1
处的 client
是 ClientTransactionHandler
的子类 ActivityThread
,查看 ActivityThread.handleLauncherActivity
的源码,主要是调用了 ActivityThread.performLaunchActivity
方法:
// /frameworks/base/core/java/android/app/ActivityThread.java
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions,
Intent customIntent) {
...
WindowManagerGlobal.initialize();
// 1 启动 Activity
final Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
// 停止 Activity 的启动
ActivityTaskManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo; // 2 获取 ActivityInfo 类
if (r.packageInfo == null) {
// 3 获取 APK 文件描述类 LoadApk
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent(); // 4
...
// 5 创建要启动的 Activity 的上下文环境
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
// 6 用类加载器创建该 Activity 的实例
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
// 7 创建 Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
...
// 8 初始化 Activity
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); // 9
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
....
}
return activity;
}
注释 1
处调用了 ActivityThread.performLaunchActivity
方法来启动 Activity
。注释 2
处用来获取 ActivityInfo
,用来存储代码以及 AndroidManifest
设置的 Activity
和 Receiver
节点信息,比如,Activity
的 theme
和 launchMode
。在注释 3
处获取 APK
文件的描述类 LoadedApk
。在注释 4
处获取要启动的 Activity
的 ComponentName
类,在 ComponentName
类中保存了该 Activity
的包名和类名。在注释 5
处用来创建要启动的 Activity
的上下文环境。在注释 6
处根据 ComponentName
中存储的 Activity
类名,用类加载器来创建该 Activity
的实例 。注释 7
处用来创建 Application
,LoadedApk.makeApplication
方法内部会调用 Application.onCreate
方法。注释 8
处调用 Activity.attach
方法初始化 Activity
,在 Activity.attach
方法中会创建 Window
对象(PhoneWindow
)并与 Activity
自身进行关联。在注释 9
处调用 Instrumentation.callActivityOnCreate
方法来启动 Activity
:
// /frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState); // 1
postPerformCreate(activity);
}
注释 1
处调用了 Activity.performCreate
方法,在 Activity.performCreate
方法中又调用了 Activity.onCreate
方法,到这里,根 Activity
就启动了,以下是相关源码:
// /frameworks/base/core/java/android/app/Activity.java
@UnsupportedAppUsage
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
dispatchActivityPreCreated(icicle);
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
// 1
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
mActivityTransitionState.readState(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
dispatchActivityPostCreated(icicle);
}
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
if (mLastNonConfigurationInstances != null) {
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
}
if (mActivityInfo.parentActivityName != null) {
if (mActionBar == null) {
mEnableDefaultActionBarUp = true;
} else {
mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
}
}
if (savedInstanceState != null) {
mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
View.LAST_APP_AUTOFILL_ID);
if (mAutoFillResetNeeded) {
getAutofillManager().onCreate(savedInstanceState);
}
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
}
mFragments.dispatchCreate();
dispatchActivityCreated(savedInstanceState);
if (mVoiceInteractor != null) {
mVoiceInteractor.attachActivity(this);
}
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
}
public void onCreate(@Nullable Bundle savedInstanceState,
@Nullable PersistableBundle persistentState) {
onCreate(savedInstanceState);
}
参考
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)