Activity深入之启动流程
Activity作为四大组件之一,一般我们在日常开发中通过以下方式拉起Activity。
Intent intent = new Intent(this,NextActivity.class);
startActivity(intent);
那么startActivity之后的流程是怎样的呢?接下来我们通过流程图加源码的方式走入底层看一看。下图是应用层视角一次完整的Activity启动流程图。
预览目录
1、Context.startActivity
2、Instrumentation.execStartActivity()
3、ActivityTaskManagerService.startActivity
4、ActivityStarter.execute
5、ActivityRecord.resumeTopActivityUncheckedLocked
6、ActivityRecord.resumeTopActivityUncheckedLocked
7、ApplicationThread.scheduleTransaction
8、ApplicationThread.performLaunchActivity
提前声明本文源码阅读基于Android11。与早些的Android版本存在一定程度的偏差。
1、Context.startActivity
startActivity调用的是Context的startActivity。而Context只是接口类,具体的实现在ContextImpl中。
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
// Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
// generally not allowed, except if the caller specifies the task id the activity should
// be launched in. A bug was existed between N and O-MR1 which allowed this to work. We
// maintain this for backwards compatibility.
final int targetSdkVersion = getApplicationInfo().targetSdkVersion;
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& (targetSdkVersion < Build.VERSION_CODES.N
|| targetSdkVersion >= Build.VERSION_CODES.P)
&& (options == null
|| ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
该方法里仅做了启动标志位的校验,若不满足则抛出异常。这个异常就是在非Activity场景下拉起抛出的异常。说的就是在非Activity场景下拉起时需要指定Intent.FLAG_ACTIVITY_NEW_TASK标志位,即在新的任务栈中创建Activity。而在Activity中拉起Activity时则会加入到已有的任务栈中。
另外一个启动入口则在Activity中。Activity类重写了startActivity,紧接着走到startActivityForResult,在该方法中也是调用的Instrumentation.execStartActivity()。
2、Instrumentation.execStartActivity()
接着看一下Instrumentation.execStartActivity(),如下所示:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intenrt, int requestCode, Bundle options) {
IApplicationThead whoThread = (IApplicationThread) contextThread;
...
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
从以上代码可以看出,实际的启动Activity是在ActivityTaskManager.getService().startActivity。通过查看getService的代码,它获取了IActivityTaskManager的单实例,Singleton是一个单例的封装类,第一次调用它的get方法则会通过create方法来初始化IActivityTaskManager这个对象。IActivityTaskManager是一个binder接口,具体的实现是在ActivityTaskManagerService
此时Activity的启动转到了ActivityTaskManagerService。与此同时这里还把 App 中 Binder 的 Server 端的 ApplicationThread 的句柄传给 ATMS,用于生命周期的回调等,如 onPause。
/** @hide */
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
3、ActivityTaskManagerService.startActivity
startActivity有几个同名不同参的函数,最后都调用到startActivityAsUser。这里需要说一下,ActivityManagerService中也有startActivity的入口,但其实最终的走向都是到达以下方法。
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);
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();
}
ActivityStartController的主要作用就是接收Activity请求并为此做准备提供给ActivityStarter。该类则收集了一系列Activity的启动Intent及参数。
4、ActivityStarter.execute
其中ActivityStarter.execute中有如下调用逻辑。
executeRequest主要做一些初步的启动检查。startActivityUnchecked确保如果启动不成功会删除启动活动。startActivityInner方法决定是否加入到已存在的任务栈顶,计算启动的 Flags,例如是否有 NEW_TASK,并设置给 intent,计算该 Activity 是否要插入到当前现有的任务栈中, 判断栈顶 Activity 是否相同,是否需要复用。
5、ActivityRecord.resumeTopActivityUncheckedLocked
resumeTopActivityUncheckedLocked里面主要调用了Activity的resume,并且调用方法checkReadyForSleep来确保onPause逻辑执行正确。进而走到resumeTopActivityInnerLocked
。该方法中先暂停当前Activity,再启动新的Activity。
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
...
mStackSupervisor.startSpecificActivity(next, true, false);
...
}
6、ActivityStackSupervisor.realStartActivityLocked
其中realStartActivityLocked有如下代码段
// 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);
其中scheduleTransaction实际是调用IApplicationThread.scheduleTransaction。从IApplicationThread的接口方法可以看出,它其中包含了启动、停止Activity的接口,此外还包含启动、停止Service的接口。
7、ApplicationThread.scheduleTransaction
其实IApplicationThread的实现者就是ApplicationThread。ApplicationThread则是ActivityThread的内部类。来看看scheduleTransaction具体做了些什么,在ApplicationThread中实现如下。
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
scheduleTransaction调用了抽象类ClientTransactionHandler的sendMessage方法。而ClientTransactionHandler的实现类其实就是ActivityThread。
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);
}
...
}
顺着查看EXECUTE_TRANSACTION这条消息的具体实现如下:
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——executeCallbacks——cycleToPath——performLifecycleSequence。
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Transitioning activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " to state: " + getStateName(state));
}
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r.token, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, 0 /* configChanges */,
mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
8、ApplicationThread.performLaunchActivity
即scheduleTransaction发送一个启动Activity的消息,交由Handler处理。这个Handler是抽象类ClientTransactionHandler,他的实现是ActivityThread。所以ActivityThread具体的实现了一系列的启动流程。
ON_CREATE则执行handleLaunchActivity,其中performLaunchActivity方法最终完成了Activity对象的创建。并且ActivityThread通过handleResumeActivity方法来调用被启动Activity的onResume这一生命周期方法。
performLaunchActivity主要做了以下几件事:
从ActivityClientRecord中获取待启动的Activity的组件信息;
通过Instrumentation的newActivity方法使用类加载器创建Activity对象;
通过LoadApk的makeAppLication方法来尝试创建Application对象。