本文简单分析一下activity的启动流程。
分析基于Android 9.0源码,有兴趣的朋友可以在AndroidStudio创建一个API28的HelloWorld工程跟着看,如果发现文章有什么问题,可以联系我。
Activity在应用内启动流程
话不多说,先上图,流程图1:
简单介绍一下涉及的类:
- Instrumentation
工具类,包装了ActivityManagerService的调用。一些插件化方案就是通过hook该类实现的,例如didi的VirtualApk
- ActivityManagerService
Android核心服务,负责调度各应用进程,管理四大组件。实现了IActivityManager接口,应用进程能通过Binder机制调用系统服务。
- ActivityStarter
Activity启动的工具类,处理启动activity的各种flag。
- ActivityStackSupervisor
管理所有应用的Activity的栈,其中mFocusedStack就是当前应用的activity栈。
- LaunchActivityItem
启动Activity的消息。收到消息后执行execute方法启动activity。
- ActivityThread
应用的主线程。
接下来开始分析流程:
流程图1,第1-3步,Activity的startActivity会调用startActivityForResult。当应用已经启动时,会先调用startActivityFromChild。但是无论应用是否启动,最后都会调用Instrumentation.execStartActivity
。
正如前面所说,ActivityManagerService实现了IActivityManager.aidl
接口,提供了应用进程调用系统服务的方法,而Instrumentation包装了ActivityManagerService的调用。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
int requestCode, @Nullable Bundle options) {
...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
...
}
流程图1,第4步,Instrumentation调用ActivityManagerService的startActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
...
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), 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;
}
流程图1,第5-6步,ActivityManagerService创建ActivityStarter并执行。
public final 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) {
...
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
流程图1,第7步,由于第6步setMayWait将mayWait设置为true,所以执行startActivityMayWait方法。
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(...);
} else {
return startActivity(...);
}
} finally {
onExecutionComplete();
}
}
流程图1,第8-11步,ActivityStarter处理启动activity的intent和flag比较繁琐,最后会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked。
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
...