Android 开发核心总是绕不过那几个模块,与 Android 的相关面试就离不开这个话题,什么,你又要开始讲述 Binder 的定义跟基础了?不不不,今天我们从 Activity 的启动来分析一波其中的代码原理和 ActivityTaskManagerService 进程间的通信过程。
本章所有源码版本基于 android-30
在 app 运行过程中,不管是 Activity 之前的跳转,还是在手机桌面应用中点击一个 icon 启动这个app,最终都是去通过 startActivity 去打开某一个 Activity 页面。我们知道 Android 中的一个 App 就相当于一个进程,所以 startActivity 操作中还需要判断,目标 Activity 的进程是否已经创建,如果没有,则在显示 Activity 之前还需要将进程 Process 提前创建出来。
所以整个 startActivity 的流程分为 4 大部分,也涉及 4 个进程之间的交互:
- 应用进程(Launcher)调用 ActivityTaskManagerService 来创建 Activity
- ActivityTaskManagerService 到 ApplicationThread 的调用过程
- ActivityTaskManagerService 向 Zygote 发送启用应用进程
- ActivityThread 启动 Activity 的过程
1. 应用进程(Launcher)调用 ActivityTaskManagerService 阶段
这一过程并不复杂,看下源码中做了哪些操作。
Activity 的 startActivity
最终调用了 startActivityForResult 方法,传入的 -1 表示不需要获取 startActivity 的结果。
typescript
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
// 最终调用
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
Activity 的 startActivityForResult
具体代码如下所示:
less
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
// mMainThread.getApplicationThread()获取当前Activity的进程。
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
...
}
}
startActivityForResult 也很简单,调用 Instrumentation.execStartActivity 方法。剩下的交给 Instrumentation 类去处理。
解释说明:
- Instrumentation 类主要用来监控应用程序与系统交互。
- mMainThread.getApplicationThread(),这个就是用来实现进程间通信的,具体来说就是 AMS 所在系统进程通知应用程序进程进行的一系列操作。
Instrumentation 的 execStartActivity
方法如下:
java
@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 前置处理
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// ActivityTaskManager.getService() 获取 ActivityTaskManagerService 的实例
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityTaskManager.getService() 获取 ActivityTaskManagerService 的实例,是使用 ActivityTaskManagerService 来调用其 startActivity 方法。
java
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
// "activity_task"
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
我们来看 getService 方法调用了 IActivityTaskManagerSingleton 的 get 方法,而它是一个 Singleton 类,在重写的 create 方法中获取 Context.ACTIVITY_TASK_SERVICE 的 IBinder 引用,然后转换成 IActivityTaskManager 类型的对象。典型的AIDL的写法,IActivityTaskManager 类是 AIDL 工具在编译时自动生成,要实现进程间通信,服务端也就是 ActivityTaskManagerService 只需要继承 IActivityTaskManager.Stub 类并实现相应的方法就可以了。
通过 AIDL 来调用 ActivityTaskManagerService 的 startActivity 方法,至此,startActivity 的工作重心成功地从进程 Activity 转移到了系统进程 ActivityTaskManagerService 中。
2. ActivityTaskManagerService 到 ApplicationThread 的调用过程
接下来就看下在 ActivityTaskManagerService 中是如何一步一步执行到目标 Activity 进程的。
- 综合处理 launchMode 和 Intent 中的 Flag 标志位,并根据处理结果生成一个目标 Activity 的对象(ActivityRecord)。
- 判断是否需要为目标 Activity 创建一个新的进程(ProcessRecord)、新的任务栈(TaskRecord)。
接下来就从 ActivityTaskManagerService 的 startActivity 方法开始看起:
ActivityTaskManagerService 的 startActivity
scss
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
// 判断调用者进程是否被隔离,如果 isIsolated 则抛出 SecurityException 异常
enforceNotIsolatedCaller("startActivityAsUser");
// 检查调用者权限
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
startActivity 和 startActivityAsUser 的主要区别仅在于方法多了一个参数 UserHandle.getCallingUserId(),该方法会获取调用者的 UserId, ActivityTaskManagerService 可以根据这个 UserId 来确定调用者的权限。
最后通过 getActivityStartController().obtainStarter(intent, "startActivityAsUser") 来获取 ActivityStarter 对象,调用 ActivityStarter 的 execute() 方法继续执行启动流程。
scss
int execute() {
try {
...
int res;
synchronized (mService.mGlobalLock) {
...
res = executeRequest(mRequest);
Binder.restoreCallingIdentity(origId);
...
}
} finally {
onExecutionComplete();
}
}
在 execute() 中,会再次调用其内部的 executeRequest 方法。
ActivityStarter 的 executeRequest
ActivityStarter 是 Android7.0 中新增的类, 它是用来加载Activity的控制类,看名字也想得到它是专门负责一个 Activity 的启动操作。它的主要作用包括解析 Intent、创建 ActivityRecord、如果有可能还要创建 TaskRecord。
executeRequest 是 ActivityStarter 的核心方法,部分实现如下:
java
private int executeRequest(Request request) {
...
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;
}
}
...
//各种错误检查
...
// 检查 intent 防火墙是否屏蔽了该 intent
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, resultStack);
abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
callingPid, resolvedType, aInfo.applicationInfo);
abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
callingPackage);
... ...
// If permissions need a review before any of the app components can run, we
// launch the review activity and pass a pending intent to start the activity
// we are to launching now after the review is completed.
if (aInfo != null) {
if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
...
// 通过 ActivityStackSupervisor 获取 ResolveInfo 信息
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
computeResolveFilterUid(
callingUid, realCallingUid, request.filterCallingUid));
// 通过 ActivityStackSupervisor 获取目标 Activity 信息
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
null /*profilerInfo*/);
...
}
}
if (rInfo != null && rInfo.auxiliaryInfo != null) {
...
// 通过 ActivityStackSupervisor 获取目标 Activity 信息
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
}
// 创建 ActivityRecord 对象
final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, callingFeatureId, intent, resolvedType, aInfo,
mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
sourceRecord);
mLastStartActivityRecord = r;
...
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
return mLastStartActivityResult;
}
可以看出获取目标 Activity 信息的操作由 ActivityStackSupervisor 来实现,主要是负责 Activity 所处栈的管理类。
ActivityStackSupervisor 中的 resolveIntent 中实际上是调用系统 PackageManagerService 来获取最佳 Activity。有时候我们通过隐式 Intent 启动 Activity 时,系统中可能存在多个 Activity 可以处理 Intent,此时会弹出一个选择框让用户选择具体需要打开哪一个 Activity 界面,就是此处的逻辑处理结果。
在 executeRequest 方法的最后会调用 startActivityUnchecked 方法来获取启动 Activity 的结果。startActivityUnchecked 方法中采用 startActivityInner 来处理目标 Activity 的信息。
ActivityStarter 的 startActivityInner
scss
@VisibleForTesting
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
// 1. 计算启动 Activity 的 Flag 值
computeLaunchingTaskFlags();
... ...
// 2. 处理 Task 和 Activity 的进栈操作
mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
newTask, mKeepCurTransition, mOptions);
// 3. 启动栈中顶部的 Activity
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
...
mTargetStack.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
...
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
return START_SUCCESS;
}
当前方法主要处理了启动 Activity 的 Flag 值、Task 和 Activity 的进栈操作以及启动栈中顶部的 Activity的相应操作,我们具体一步一步分析。
computeLaunchingTaskFlags 方法具体如下:
csharp
private void computeLaunchingTaskFlags() {
... 前置处理 Task 和 Intent 的信息
if (mInTask == null) {
if (mSourceRecord == null) {
// 使用 Context 或者 Application 启动 Activity 时,mSourceRecord 为空
if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
"Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
}
} else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
// 初始 Activity 如果是在 SingleInstance 栈中的 Activity,这种需要添加 NEW_TASK 的标识。
// 因为 SingleInstance 栈只能允许保存一个 Activity。
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
} else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
// 如果 Launch Mode 设置了 singleTask 或 singleInstance,则也要创建一个新栈。
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
}
}
}
这个方法的前置部分处理完 Task 和 Intent 的信息,根据 Task 和 ActivityRecord 的类型来判断如何给目标 Activity 增加相应的启动 Flag。不同的 Flag 决定了启动 Activity 最终会被放置到哪一个 Task 集合中。
ActivityStackSupervisor 的 startActivityLocked
java
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
Task rTask = r.getTask();
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
final boolean isOrhasTask = rTask == this || hasChild(rTask);
// mLaunchTaskBehind tasks get placed at the back of the task stack.
if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
positionChildAtTop(rTask);
}
...
}
方法中会调用 positionChildAtTop 方法尝试将 Task 和 Activity 入栈。如果 Activity 是以 newTask 的模式启动或者 TASK 堆栈中不存在该 Task id,则 Task 会重新入栈,并且放在栈的顶部。需要注意的是:Task 先入栈,之后才是 Activity 入栈,它们是包含关系。
RootWindowContainer 的 resumeFocusedStacksTopActivities 和 updateUserStack
在 RootWindowContainer 的 resumeTopActivityUncheckedLocked 方法中经过一系列调用,期间经过ActivityStack 处理、最终代码到了 ActivityStackSupervisor 中的 startSpecificActivity 方法。
ActivityStackSupervisor 的 startSpecificActivity
java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 根据进程名称和 Application 的 uid 来判断目标进程是否已经创建,如果没有则代表进程未创建。
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
// 执行启动 Activity 的操作
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
// 调用 ActivityTaskManagerService 创建 Activity 所在进程。
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
根据源码我们发现不管是目标进程是否为新建,最终都会调用 realStartActivityLocked 方法来执行启动 Activity 的操作。
ActivityStackSupervisor 的 realStartActivityLocked
scss
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
try {
...
try {
...
// Activity 的启动交给了事务(Transaction)来完成
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
} catch (RemoteException e) {
throw e;
}
} finally {
endDeferResume();
}
...
return true;
}
可以看到 Activity 的启动交给了事务(ClientTransaction)来完成。由 ClientTransaction 来创建 Activity 启动事务,并传入 app.thread 参数,并在之后调用 scheduleTransaction 方法来执行 Activity 启动事务。
Activity 启动事务的执行是由 ClientLifecycleManager 来完成的,具体代码如下:
java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
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();
}
}
可以看出实际上是调用了启动事务 ClientTransaction 的 schedule 方法,而这个 transaction 实际上是在创建 ClientTransaction 时传入的 app.thread 对象,也就是 ApplicationThread。如下所示:
ini
/** Obtain an instance initialized with provided params. */
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}
传入的 app.thread 会赋值给 ClientTransaction 的成员变量 mClient,所以 mClient 变量就是 IApplicationThread 对象即 ActivityThread 的内部类 ApplicationThread,其中 ApplicationThread 继承了 IApplicationThread.Stub。 所以事务最终是调用 app.thread 的 scheduleTransaction 执行。这里通过 IApplicationThread 来与应用进程进行 Binder 通信。所以代码回到了 ApplicationThread.ActivityThread 上。
到这为止 startActivity 操作就成功地从 ActivityTaskManagerService 转移到了目标 Activity 中的 ApplicationThread 中,剩下的就是 ActivityTaskManagerService 通过进程间通信机制通知 ApplicationThread 执行 Activity 的生命周期方法。
3. ActivityTaskManagerService 向 Zygote 发送启用应用进程
在之前 ActivityStackSupervisor 的 startSpecificActivity 方法中,我们看到由 ActivityTaskManagerService 的 startProcessAsync 方法来请求启动新的应用进程。仔细查看其中主要是调用了 ActivityManagerService 的 startProcess 方法
ActivityManagerService 的 startProcess
typescript
// ActivityManagerInternal 类
/** Starts a given process. */
public abstract void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);
// ActivityManagerService 类
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, 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) {
// If the process is known as top app, set a hint so when the process is
// started, the top priority can be applied immediately to avoid cpu being
// preempted by other processes before attaching the process of top app.
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
里面主要是 startProcessLocked 方法
java
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
keepIfLarge, null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
根据一系列的调用,最终可以看到是由 ProcessList 中的 startProcess 方法处理,核心是进行到 Process 的 start 方法。
Process 的 start 方法
less
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
}
不难发现 Process 的 start 方法只调用了 ZYGOTE_PROCESS 的 start 方法,ZYGOTE_PROCESS 类是用于保持与 Zygote 进程的通信状态。
ZygoteProcess 中的 start 方法核心是调用了 startViaZygote 方法,在这个方法最后我们发现
scss
synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
这里面的第一个参数调用了openZygoteSocketIfNeeded方法,这里会调用 ZygoteState 的 connect 方法与 Zygote 建立连接。
而 ZygoteProcess 的 zygoteSendArgsAndGetResult 方法主要是将传入的应用进程的启动参数 argsForZygote 写入到 ZygoteState 中。
到此就完成了 ActivityTaskManagerService 向 Zygote 发送启用应用进程。
4. ActivityThread 启动 Activity 的过程
在第三个章节我们分析了 ActivityTaskManagerService 将启动 Activity 的任务作为一个事务 ClientTransaction 去完成,在 ClientLifecycleManager 中会调用 ClientTransaction的schedule() 方法,而 mClient 是一个 IApplicationThread 接口类型,具体实现是 ActivityThread 的内部类 ApplicationThread。因此后续执行 Activity 生命周期的过程都是由 ApplicationThread 指导完成的,而调用 ActivityThread 的 scheduleTransaction 方法,而 ActivityThread 是继承自抽象类 ClientTransactionHandler,ActivityThread 没有重写该方法,所以这里就会调用到 ClientTransactionHandler 的 scheduleTransaction 方法。具体如下:
csharp
public abstract class ClientTransactionHandler {
// Schedule phase related logic and handlers.
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
调用 sendMessage 方法,向 Handler 中发送了一个 EXECUTE_TRANSACTION 的消息,并且 Message 中的 obj 就是启动 Activity 的事务对象。而这个 Handler 的具体实现是 ActivityThread 中的 mH 对象。源码如下:
scala
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
@UnsupportedAppUsage
final H mH = new H();
final Executor mExecutor = new HandlerExecutor(mH);
class H extends Handler {
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);
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;
}
}
}
}
可以看到这个消息被 TransactionExecutor 处理了,执行了其中的 execute 方法
scss
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
内部是由 executeCallback 方法处理的
TransactionExecutor 的 executeCallback
ini
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
}
if (postExecutionState != UNDEFINED && r != null) {
// Skip the very last transition and perform it by explicit state request instead.
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
这里 callbacks 列表中存放的是第二阶段中 ActivityStackSupervisor 的 realStartActivityLocked 方法
中创建事务时设置进去的。即 LaunchActivityItem 所以这里是执行 LaunchActivityItem 对象的 execute 方法。
LaunchActivityItem 的 execute()
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, mFixedRotationAdjustments);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
其中的 handleLaunchActivity 是不是以及非常熟悉了,终于到了跟 Activity 生命周期相关的方法了,源码中 client 是 ClientTransationHandler 类型,实际实现类就是 ActivityThread。所以我们可以看一下 ActivityThread 中的 handleLaunchActivity 方法了。
ActivityThread 的 handleLaunchActivity
这是一个比较重要的方法,Activity 的生命周期方法就是在这个方法中有序执行,具体如下:
scss
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
// 初始化 Activity 的 WindowManager
if (ThreadedRenderer.sRendererEnabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
HardwareRenderer.preload();
}
WindowManagerGlobal.initialize();
// Hint the GraphicsEnvironment that an activity is launching on the process.
GraphicsEnvironment.hintActivityLaunch();
// 调用 performLaunchActivity 创建并显示 Activity
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
可以看到里面最核心的两个方法就是初始化 Activity 的 WindowManager,以及调用 performLaunchActivity 创建并显示 Activity。
ActivityThread 的 performLaunchActivity
java
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
// 通过反射创建目标 Activity 对象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
...
} catch (Exception e) {
...
}
try {
if (activity != null) {
...
// 调用 attach 方法建立 Activity 与 Context 之间的联系,创建 PhoneWindow 对象,并与 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.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
...
// 通过 Instrumentation 最终调用 Activity 的 onCreate 方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
} catch (Exception e) {
...
}
return activity;
}
可以看到在 performLaunchActivity 方法中主要完成下面三件事:
- 通过反射创建目标 Activity 对象。
- 调用 attach 方法建立 Activity 与 Context 之间的联系,创建 PhoneWindow 对象,并与 Activity 进行关联操作。
- 通过 Instrumentation 最终调用 Activity 的 onCreate 方法。
Instrumentation 的 callActivityOnCreate
scss
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
performCreate 中会调用 Activity 的 onCreate。Activity 的启动就完成了。
至此,目标 Activity 已经被成功创建并执行生命周期方法。
总结
不得不说,Android 每一个版本之前源码都是有一些变动的,今天我们分析了基于 android-30 版本的Activity 的启动的实现流程。这一过程主要涉及 4 个进程间的通信过程:
- 首先 Launcher 进程通过 Binder 调用 ActivityTaskManagerService 的 startActivity 方法。
- 然后 ActivityTaskManagerService 通过一系列的计算构造目标 Intent,然后在 ActivityStack 与 ActivityStackSupervisor 中处理 Task 和 Activity 的入栈操作。
- ActivityTaskManagerService 通过 socket 调用向 Zygote 发送启用应用进程来达到创建应用进程的目的。
- 最后 ActivityTaskManagerService 通过 Binder 机制,调用目标进程中 ApplicationThread 的方法来创建并执行 Activity 生命周期方法,实际上 ApplicationThread 是 ActivityThread 的一个内部类,它的执行最终都调用到了 ActivityThread 中的相应方法。