Activity启动流程总结
1. 应用进程启动 Activity
当应用中的某个 Activity 调用 startActivity 方法时,实际上是通过 ContextImpl 类中的 startActivity 方法发起的。
public class ContextImpl extends Context {
@Override
public void startActivity(Intent intent) {
// 调用 Instrumentation 的 startActivity 方法
mInstrumentation.execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, null);
}
}
2. 通过 Instrumentation 发起请求
ContextImpl 会调用 Instrumentation 类中的 execStartActivity 方法来处理启动请求。
public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread appThread = (IApplicationThread) contextThread;
// 通过 Binder 调用 AMS(ActivityTaskManagerService)
int result = ActivityTaskManager.getService().startActivity(
appThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
return new ActivityResult(result, null);
}
}
3. 跨进程通信到 ActivityTaskManagerService (ATMS)
startActivity 请求通过 Binder 机制传递给系统服务进程中的 ActivityTaskManagerService(ATMS)。ATMS 是运行在 SystemServer 进程中的一个服务,负责管理所有应用的 Activity 生命周期和任务栈。
ATMS 处理启动请求
在 ATMS 中,启动 Activity 的逻辑主要由 ActivityStarter 类处理。它会解析 Intent 并根据启动模式(如 singleTask、singleInstance 等)决定如何启动或复用 Activity。
public class ActivityStarter {
public int startActivityMayWait(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int flags, ProfilerInfo profilerInfo, Bundle options) {
// 解析 Intent 和启动模式
TaskRecord task = findTaskForActivity(intent.getComponent());
if (task != null && isSingleTaskMode(intent)) {
// 如果任务栈已存在且是 singleTask 模式
bringTaskToFront(task);
return START_TASK_TO_FRONT;
} else {
// 创建新的任务栈并启动 Activity
TaskRecord newTask = createNewTask(intent);
startNewActivity(newTask, intent);
return START_SUCCESS;
}
}
private boolean isSingleTaskMode(Intent intent) {
// 判断是否是 singleTask 模式
return intent.getComponent().getLaunchMode() == ActivityInfo.LAUNCH_SINGLE_TASK;
}
private TaskRecord findTaskForActivity(ComponentName componentName) {
// 查找包含指定 Activity 的任务栈
for (TaskRecord task : mTaskStacks) {
if (task.containsActivity(componentName)) {
return task;
}
}
return null;
}
private void bringTaskToFront(TaskRecord task) {
// 将任务栈置于前台,并清理位于目标 Activity 之上的所有 Activity
moveTaskToFront(task);
}
private void moveTaskToFront(TaskRecord task) {
// 将任务栈置于前台
mTaskStacks.remove(task);
mTaskStacks.add(task); // 或者使用特定的方法将任务栈置于前台
}
private TaskRecord createNewTask(Intent intent) {
// 创建新的任务栈
TaskRecord newTask = new TaskRecord();
// 设置任务栈属性
return newTask;
}
private void startNewActivity(TaskRecord task, Intent intent) {
// 启动新的 Activity 并将其添加到任务栈中
ActivityRecord activityRecord = new ActivityRecord(intent);
task.addActivity(activityRecord);
}
}
4. 通知客户端启动 Activity
一旦 ATMS 决定了如何启动或复用 Activity,它会通过 ApplicationThread 通知客户端应用启动新的 Activity。这个过程涉及到 Binder 调用,具体是通过 IApplicationThread 接口进行的。
public interface IApplicationThread {
void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo);
}
5. 客户端应用处理启动请求
在客户端应用进程中,ApplicationThread 实现了 IApplicationThread 接口,并且在收到 scheduleLaunchActivity 调用后,会将请求转发给 ActivityThread 的 handleLauncherActivity 方法。
public class ActivityThread {
final ApplicationThread mAppThread = new ApplicationThread();
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
sendMessage(H.LAUNCH_ACTIVITY, new ActivityClientRecord(r, data));
}
}
private void handleLauncherActivity(ActivityClientRecord r) {
// 创建并启动 Activity
ClientTransaction transaction = ClientTransaction.obtain(applicationThread, r.token);
transaction.addCallback(LaunchActivityItem.obtain(r.intent, r.info,
new Configuration(), r.compatInfo, r.referrer, r.voiceInteractor, windowIsFloating,
r.config, r.overrideConfig, r.pendingResults, r.pendingNewIntents,
mLastNonConfigurationInstances, r.isForward, profilerInfo));
executeTransaction(transaction);
}
private void executeTransaction(ClientTransaction transaction) {
// 执行事务,包括创建和启动 Activity
Activity activity = performLaunchActivity(transaction.getActivityClientRecord());
if (activity != null) {
performResumeActivity(transaction.getActivityClientRecord());
}
}
private Activity performLaunchActivity(ActivityClientRecord r) {
// 创建 Activity 实例
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
...
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);
...
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
activity.mCalled = false;
mInstrumentation.callActivityOnCreate(activity, r.state);
...
return activity;
} catch (Exception e) {
...
}
}
}
关键点解释
-
跨进程通信:
- 客户端通过
Binder调用ActivityTaskManagerService(ATMS)的方法来启动Activity。 ATMS处理任务栈和ActivityRecord,决定如何启动或复用Activity。
- 客户端通过
-
任务栈管理:
ActivityTaskManagerService使用ActivityStarter类来解析Intent并根据启动模式决定如何启动或复用Activity。- 如果需要启动新的
Activity,则将其添加到适当的任务栈中;如果需要复用现有实例,则调整任务栈以确保该实例位于栈顶。
-
通知客户端:
ActivityTaskManagerService通过ApplicationThread通知客户端应用启动新的Activity。ApplicationThread实现了IApplicationThread接口,并在收到scheduleLaunchActivity调用后,将请求转发给ActivityThread的handleLauncherActivity方法。
-
启动
Activity:- 在客户端应用进程中,
ActivityThread的handleLauncherActivity方法负责创建并启动Activity实例。 performLaunchActivity方法用于创建Activity实例,并调用其生命周期方法(如onCreate、onStart等)。
- 在客户端应用进程中,
总结
以下是经过整理后的完整流程:
-
应用进程启动
Activity:- 应用中的某个
Activity调用startActivity方法,实际通过ContextImpl类中的startActivity方法发起请求。
- 应用中的某个
-
通过
Instrumentation发起请求:ContextImpl调用Instrumentation类中的execStartActivity方法来处理启动请求。
-
跨进程通信到
ActivityTaskManagerService(ATMS):startActivity请求通过Binder机制传递给系统服务进程中的ActivityTaskManagerService(ATMS)。- ATMS 解析
Intent并根据启动模式决定如何启动或复用Activity。
-
通知客户端启动
Activity:- ATMS 通过
ApplicationThread通知客户端应用启动新的Activity。 ApplicationThread实现了IApplicationThread接口,并在收到scheduleLaunchActivity调用后,将请求转发给ActivityThread的handleLauncherActivity方法。
- ATMS 通过
-
客户端应用处理启动请求:
- 在客户端应用进程中,
ActivityThread的handleLauncherActivity方法负责创建并启动Activity实例。 performLaunchActivity方法用于创建Activity实例,并调用其生命周期方法(如onCreate、onStart等)。
- 在客户端应用进程中,
通过这一系列步骤,Android 系统能够高效地管理和调度 Activity 的生命周期,确保应用的正常运行。

浙公网安备 33010602011771号