一 概述
Activity 的启动分为不同进程间和相同进程内部的启动。由于进程间 Activity 启动流程包括了相同进程内部 Activity 启动的流程。因此本文只分析不同进程间,比如点击 Launcher 桌面图标启动 Activity 的整个过程。在阅读本篇文章之前,建议同学们先了解下 AMS 相关的数据结构和管理机制,可参考 Android四大组件系列1 AMS相关数据结构。
时序图如下:
涉及代码如下:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
frameworks/base/services/core/java/com/android/server/wm/ActivityDisplay.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/ActivityTaskManager.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/AppComponentFactory.java
frameworks/base/core/java/android/app/FragmentController.java
frameworks/base/core/java/android/app/ClientTransactionHandler.java
frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java
frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
二 startActivity阶段
我们知道,我们可以在自己的应用中的 Activity 中通过 startActivity 就可以发送一个 Intent 然后启动一个新的应用,这里边调用的就是 Activity.startActivity,我们来看这个函数,需要注意的是这些个操作都是在发起端进程中执行的。这个发起端可以是 Launcher,也可以是任何调用 startActivity 的应用。
2.1 Activity.startActivity
frameworks/base/core/java/android/app/Activity.java
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
2.2 Activity.startActivityForResult
public void startActivityForResult(@RequiresPermission Intent intent,
int requestCode) {
// 从当前应用进程跨进程跳转到了 AMS
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent,
int requestCode, @Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
// 调用 Instrumentation 的 execStartActivity 方法,继续执行
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;
}
......
} else {
......
}
}
2.3 Instrumentation.execStartActivity
frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, ......) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
......
try {
......
// 跨进程调用 ActivityTaskManagerService.startActivity
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// 检查 result, 判断 Activity 是否启动成功.
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
- who:启动 Activity 的上下文
- contextThread:ActivityThread 中的 ApplicationThread 对象 mAppThread
- token:令牌,标识着 Activity,系统唯一标识
- target:在哪个 Activity 中启动,会接收启动完成的结果
- intent:启动意图
- requestCode:请求码,用于将结果和请求对应上
- options:可选参数
execStartActivity 里面我们需要重点关注两个参数。
mMainThread.getApplicationThread() 会返回一个 ApplicationThread 类型的变量。这个变量我们在 Android四大组件系列1 AMS相关数据结构 中已经介绍过,这里 ApplicationThread 代表的是发起请求的客户端进程,后面 AMS 就是通过它来和客户端进程进行跨进程通信的。
第二个需要重点关注的就是 mToken,mToken 我们在之前也介绍过了,它是连接 ActivityRecord,Activity,ActivityClientRecord 的桥梁,AMS 通过它就可以获取客户端进程中的 Activity 的详细信息。
最后通过 Binder 调用 ActivityTaskManagerService 的 startActivity 函数,之前讲过 ATMS 是用来分担 AMS 的一些功能的。从这个地方开始就从当前应用进程跨进程跳转到了 AMS,接下来我们来看 AMS 是怎么处理响应的。
2.4 ActivityTaskManagerService.startActivity
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public final int startActivity(IApplicationThread caller,
String callingPackage, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions) {
// 指定启动 Activity 的 userId
return startActivityAsUser(caller, callingPackage, intent,
resolvedType, resultTo, resultWho, requestCode, startFlags,
profilerInfo, bOptions, UserHandle.getCallingUserId());
}
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
// 继续调用 startActivityAsUser
return startActivityAsUser(caller, callingPackage, intent,
resolvedType, resultTo, resultWho, requestCode, startFlags,
profilerInfo, bOptions, userId, true /*validateIncomingUser*/);
}
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
// 确保调用进程不是 isolated
enforceNotIsolatedCaller("startActivityAsUser");
// 检查 userId 的有效性, 并返回有效的 userId
userId = getActivityStartController().checkTargetUser(userId,
validateIncomingUser, Binder.getCallingPid(),
Binder.getCallingUid(), "startActivityAsUser");
// ActivityStartController#obtainStarter(),拿到 ActivityStarter
// ActivityStarter#execute(),启动 Activity
return getActivityStartController().obtainStarter(intent,
"startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
在 ATMS 的 startActivityAsUser 方法中会获取并初始化 ActivityStater 对象,然后调用它的 execute 方法,用来启动 Activity。注意倒数第二个 setMayWait() 方法,会将 mRequest.mayWait 属性设为 true。
ActivityStarter.java
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
2.5 ActivityStarter.execute
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
try {
if (mRequest.mayWait) {
// 需要等待请求返回结果
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid,
......);
} else {
return startActivity(mRequest.caller, mRequest.intent,
mRequest.ephemeralIntent, mRequest.resolvedType,
......);
}
} finally {
onExecutionComplete();// 执行完成
}
}
由上面的分析可知,这里的 mRequest.mayWait 为 true,是在上一步创建 ActivityStarter 实例时,通过调用 setMayWait 设置的。
2.6 ActivityStarter.startActivityMayWait
private int startActivityMayWait(IApplicationThread caller, int callingUid,
......) {
......
// PakageManagerService 解析 intent(要启动的 APP 的 intent),
// 获取 Activity 更多的信息
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType,
userId, 0 /* matchFlags */,
computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
......
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(
intent, rInfo, startFlags, profilerInfo);
synchronized (mService.mGlobalLock) {
......
final ActivityRecord[] outRecord = new ActivityRecord[1];
// 调用 startActivity
int res = startActivity(caller, intent, ephemeralIntent,
......);
......
return res;
}
}