Android Activity启动流程详细分析
概述
Activity启动是Android系统中最核心的功能之一。本文将从Activity的startActivity方法开始,一步一步详细分析Activity是如何启动另一个Activity的完整流程。整个流程涉及应用进程和系统进程之间的协作,通过Binder IPC进行通信。
启动流程总览
Activity启动流程可以分为三个主要阶段:
- 应用进程准备阶段
- 系统进程决策与调度阶段
- 应用进程执行阶段
详细启动流程分析
1. 应用进程准备阶段
1.1 Activity.startActivity() 方法调用
当我们在Activity中调用startActivity(Intent intent)方法时,实际调用的是Activity类中的以下代码:
less
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
getAutofillClientController().onStartActivity(intent, mIntent);
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);
}
}
1.2 Activity.startActivityForResult() 方法
startActivityForResult方法进一步处理启动请求:
less
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
}
这里将启动任务委托给了Instrumentation类。
1.3 Instrumentation.execStartActivity() 方法
Instrumentation是应用进程与系统进程之间的桥梁,它的execStartActivity()方法负责执行实际的启动操作:
java
@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
//获取到 IActivityTaskManager,实际就是 ActivityTaskManagerService
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), 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()获取到系统服务的Binder代理对象,然后调用其startActivity()方法,这是一个跨进程调用。
2. 系统进程决策与调度阶段
2.1 ActivityTaskManagerService接收请求
系统进程中的ActivityTaskManagerService(ATMS)接收到来自应用进程的启动请求:
arduino
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
scss
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) {
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// getActivityStartController返回的是 ActivityStarter
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();
}
2.2 ActivityStarter.execute() 方法
ActivityStarter是启动Activity的"大脑",负责所有的校验和决策逻辑:
scss
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
2.3 startActivityMayWait() 方法
当需要等待Activity启动结果时(通常情况),会调用startActivityMayWait()方法:
java
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
// 1. 检查Intent中的文件描述符,防止泄露
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
// 2. 解析Intent获取目标Activity信息
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
0 /* matchFlags */, computeResolveFilterUid(
callingUid, requestRealCallingUid, mRequest.filterCallingUid));
// 3. 获取ActivityInfo
ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
}
// 4. 处理特殊情况(如重量级应用、托管应用等)
// ...
// 5. 调用startActivity()方法继续执行
return startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outActivity, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
}
2.4 startActivity() 方法
startActivity()方法是核心的启动方法:
arduino
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
// 1. 权限检查
// 2. Intent解析
// 3. 创建ActivityRecord对象
// 4. 调用startActivityUnchecked()方法
return startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
}
2.5 startActivityUnchecked() 方法
这是Activity启动流程中最核心的方法,负责具体的启动逻辑:
scss
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
// 1. 初始化状态
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord,
voiceSession, voiceInteractor, restrictedBgActivity);
// 2. 计算启动标志
computeLaunchingTaskFlags();
// 3. 计算源任务栈
computeSourceStack();
// 4. 查找可复用的Activity
ActivityRecord reusedActivity = getReusableIntentActivity();
// 5. 处理复用情况
if (reusedActivity != null) {
// 如果找到可复用的Activity
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
setTaskFromIntentActivity(reusedActivity);
// ...
} else {
// 6. 处理不复用情况
// 根据不同情况调用不同的任务创建方法
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
// 创建新任务
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
} else if (mSourceRecord != null) {
// 在源任务中启动
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
// 在指定任务中启动
result = setTaskFromInTask();
} else {
// 在当前顶部任务中启动
result = setTaskToCurrentTopOrCreateNewTask();
}
}
// 7. 权限处理
mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
// 8. 启动Activity
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
// 9. 恢复Activity
if (mDoResume) {
mRootActivityContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
return START_SUCCESS;
}
2.6 任务栈管理
在startActivityUnchecked()方法中,系统会根据launch mode和Intent flags来决定如何管理任务栈:
- setTaskFromReuseOrCreateNewTask() : 创建新任务或复用现有任务
- setTaskFromSourceRecord() : 在源Activity的任务中启动
- setTaskFromInTask() : 在指定任务中启动
- setTaskToCurrentTopOrCreateNewTask() : 在当前顶部任务中启动
3. 应用进程执行阶段
3.1 跨进程回调应用进程
系统进程通过Binder IPC回调到目标Activity所在的应用进程。这个回调的接收者是ApplicationThread。
3.2 ApplicationThread接收回调
ApplicationThread是ActivityThread的内部类,它是一个Binder对象,运行在应用进程中。它接收到scheduleTransaction()调用,其中包含了启动Activity的指令。
3.3 H(Handler)处理消息
ApplicationThread将接收到的Binder调用转换成Message,通过一个Handler(名为H)发送到应用进程的主线程消息队列中。
3.4 ActivityThread处理指令
主线程的H处理消息,调用ActivityThread的handleLaunchActivity()方法:
scss
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// 1. 创建Activity实例
Activity a = performLaunchActivity(r, customIntent);
// 2. 调用Activity的onResume方法
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
}
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && pendingActions != null);
}
return a;
}
3.5 performLaunchActivity() 创建Activity
ini
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
return null;
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 1. 通过类加载器创建Activity实例
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
// 2. 创建Application实例(如果尚未创建)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// 3. 创建ContextImpl
ContextImpl appContext = createBaseContextForActivity(r);
// 4. 调用Activity.attach()绑定上下文
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);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
// 5. 调用Activity的onCreate方法
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// ...
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
4. 后续生命周期调用
在handleLaunchActivity()之后,系统进程会继续通过同样的IPC -> Handler机制,依次调度start、resume等方法。
关键概念详解
Launch Mode
Android支持四种启动模式:
- standard:默认模式,每次启动都会创建新实例
- singleTop:如果Activity已在栈顶,则复用并调用onNewIntent()
- singleTask:在整个系统中只有一个实例,会清除其上的所有Activity
- singleInstance:独占一个任务栈,只有一个实例
Intent Flags
常用的Intent Flags:
- FLAG_ACTIVITY_NEW_TASK:在新任务中启动Activity
- FLAG_ACTIVITY_CLEAR_TOP:清除目标Activity之上的所有Activity
- FLAG_ACTIVITY_SINGLE_TOP:如果Activity已在栈顶则复用
- FLAG_ACTIVITY_NO_HISTORY:Activity不会保留在历史栈中
启动流程时序图
scss
客户端ActivityInstrumentationActivityTaskManagerServiceActivityStarterActivityStack目标应用进程ActivityThreadActivitystartActivity()startActivity() [IPC]obtainStarter().execute()startActivityMayWait()startActivity()startActivityUnchecked()setInitialState()computeLaunchingTaskFlags()computeSourceStack()getReusableIntentActivity()setTargetStackAndMoveToFrontIfNeeded()setTaskFromIntentActivity()setTaskFromReuseOrCreateNewTask()/setTaskFromSourceRecord()alt[ 找到可复用Activity ][ 未找到可复用Activity ]startActivityLocked()scheduleLaunchActivity() [IPC]H.handleMessage()handleLaunchActivity()performLaunchActivity()onCreate()scheduleResumeActivity() [IPC]H.handleMessage()onResume()alt[ 需要恢复 ]客户端ActivityInstrumentationActivityTaskManagerServiceActivityStarterActivityStack目标应用进程ActivityThreadActivity
总结
Activity启动流程是一个复杂而精密的过程,涉及多个组件的协作:
- 应用进程负责发起启动请求,并在系统调度后执行具体的生命周期方法
- 系统进程(ATMS/ActivityStarter)负责权限检查、Intent解析、任务栈管理等核心决策
- Binder IPC是应用进程和系统进程之间通信的桥梁
- Instrumentation作为监控钩子,贯穿整个启动流程
- ActivityStack负责管理Activity的回退栈
理解这个流程对于Android开发和系统优化都有重要意义,特别是在处理启动性能、任务管理、生命周期等问题时。