1. 前言
由于系统极强的封装特性,我们在启动 Activity 时并不知道系统内部都是如何完成整个的启动流程的?如何创建一个 Activity 对象?什么时候调用 onCreate() 方法的?
本文中所有源码都是基于 Android API 29。
2. Activity 的启动方式
Activity 的启动可以通过 startActivity()
或者 startActivityForResult()
,两者的区别在于是否要接收来自被启动 Activity 的返回结果。
Intent intent = new Intent(activity, CaptureActivity.class);
activity.startActivity(intent); //不接收来自 CaptureActivity 的返回结果
Intent intent = new Intent(activity, CaptureActivity.class); //接收来自 CaptureActivity 的返回结果
activity.startActivityForResult(intent, REQUEST_CAPTURE);
3. 源码解析
3.1 启动 Activity
无论我们是通过 startActivity() 各种重载的方法还是通过 startActivityForResult() 方法启动 Activity,最后都会调用 Activity 的 startActivityForResult(Intent intent, int requestCode, Bundle options)。Context 是一个抽象类,有抽象方法 startActivity,ContextWrapper 继承自 Context ,是 Context 的代理类,实现了 startActivity;Activity 继承自 ContextWrapperTheme,ContextWrapperTheme 继承自 ContextWrapper,所以最终在 Activity 中实现的 startActivity 实际上是抽象类 Context 中的 startActivity 方法。
-
startActivityForResult()
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
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;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
1)mParent,是一个 Activity 对象,表示当前 Activity 的父 Activity,判断 mParent 是否为空,为空直接执行步骤4,不为空执行2,3;
2)mInstrumentation.execStartActivity,调用了 Instrumentation 的 execStartActivity 方法;
3)mMainThread.sendActivityResult,如果步骤2中返回结果不为空,调用ActivityThread 的 sendActivityResult 方法;
4)mParent 为空,调用父 Activity 的 startActivityFromChild 方法;
先来看看步骤2中 Instrumentation 的 execStartActivity 方法,在这里利用了 Binder 机制,跨进程调用了 ATMS(ActivityTaskManagerService)的 startActivity 方法,ATMS 运行在系统服务进程中。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.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)ActivityTaskManager.getService().startActivity 即是调用了 ATMS 的 startActivity 方法;
2)checkStartActivityResult(),检查启动 Activity 的结果。
先来看 checkStartActivityResult 方法,主要是检查启动 Activity 的结果,有异常则抛出。例如下面代码中是一个典型的未找到启动 Activity 的异常,因为我们没有在 AndroidManifest 文件中声明我们的 Activity。
public static void checkStartActivityResult(int res, Object intent) {
if (!ActivityManager.isStartResultFatalError(res)) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
...
}
}
接着来看 ActivityTaskManager 的 getService 方法:
-
ActivityTaskManager
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton IActivityTaskManagerSingleton =
new Singleton() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
这里是通过 Singleton 返回了一个 IActivityTaskManager 对象,Singleton 是一个单例的封装类,第一次调用它的get 方法时它会通过 create 方法来初始化一个 IActivityTaskManager,IActivityTaskManager 其实是一个 Binder 对象,负责应用和 ActivityTaskManagerService (以下简称 ATMS)直接的通信。
ATMS 运行在服务进程(system_server)中,Instrumentation 实现了应用和 ATMS 之间的通信,Activity 的启动就转移到了 ATMS 中:
-
ActivityTaskManagerService
ATMS 中 startActivity 方法调用了 startActivityAsUser 方法,startActivityAsUser 调用了 ActivityStarter 的 execute 方法。
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) {
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
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();
}
getActivityStartController() 获取到 ActivityStarController 对象,调用 ActivityStarController 的 obtainStarter() 获取 ActivityStarter 对象,ActivityStart 设置一些需要传给应用进程的信息,然后调用了 ececute 方法。
-
ActivityStarter
execute 方法根据启动请求调用 startActivityMayWait 方法或者 startActivity 方法,直接来看 startActivity 方法,startActivity 方法调用了 startActivityUnchecked 方法,startActivityUnchecked 调用了 ActivityTask 的 sendActivityResultLocked 方法。
//ActivityStarter
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(...);
} else {
return startActivity(...);
}
} finally {
onExecutionComplete();
}
}
private ActivityStack mTargetStack;
//ActivityStarter#startActivityUnchecked()
mTargetStack.startActivityResultLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
-
ActivityTask
sendActivityResultLocked 方法通过 ActivityTaskManagerService 调用了 ClientLifecycleManager
的 scheduleTransaction 方法
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
scheduleTransaction 方法通过 ClientTransaction 的 schedule 方法调用了 IApplicationThread
的 scheduleTransaction 方法。
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
-
IApplicationThread 和 ApplicationThread
IApplicationThread 继承了 IInterface 接口,它是一个 Binder 类型的接口,IApplicationThread 的最终实现类是 ActivityThread 的内部类 ApplicationThread
。ApplicationThread 继承自 ApplicationThreadNative
,ApplicationThreadNative 继承自 Binder 并实现来 IApplicationThread 接口。ApplicationThreadNative 的作用和使用 AIDL 时系统生成的类是一样,它的内部有一个 ApplicationThreadProxy 类,这个类也就是 AIDL 文件的代理类。综上所述,IApplicationThread 的实现类就是 ApplicationThreadNative,而 ApplicationThreadNative 被定义为了抽象类,那最终实现者就是 ApplicationThread。
-
ActivityThread
ApplicationThread 的 scheduleTransaction 方法调用了 ActivityThread 的 scheduleTransaction 方法,ActivityThread 继承自 ClientTransactionHandler
,ClientTransactionHandler 是抽象类,它的 scheduleTransaction 方法中调用 sendMessage 方法发送了一条 EXECUTE_TRANSACTION 类型的消息,sendMessage 是抽象方法,ActivityThread 实现了该方法,ActivityThread 的 sendMessage
方法中将要发送的消息封装在 Message 中,通过 ActivityThread 的 H
对象 mH 执行了消息的发送,H 是 ActivityThread 的静态内部类,继承自 Handler,用于接收并处理来自其他线程的消息。
//ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
abstract void sendMessage(int what, Object obj);
//ActivityThread
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
...
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
ActivityThread 中,H
收到 EXECUTE_TRANSACTION 类型的消息,调用 TransactionExecutor
的 execute 方法,execute 方法调用了 executeCallbacks 方法,executeCallbacks 中调用 LaunchActivityItem
的 execute 方法,LaunchActivityItem 继承自 ClientTransactionItem 并实现了 execute 方法,execute 方法调用了 ClientTransactionHandler
的 handleLaunchActivity 方法,ActivityThread 继承自 ClientTransactionHandler ,并实现了 handleLaunchActivity 方法,这里又回到了 ActivityThread
中的 handleLaunchActivity 方法内,handleLaunchActivity 方法调用了 performLaunchActivity 方法。
-
performLaunchActivity 方法:
1)从 ActivityClientRecord
中获取待启动 Activity 的启动信息;
2)调用 createBaseContextForActivity 方法创建 ContextImpl
对象,该方法中调用 ContextImpl 的 createActivityContext 方法创建 ContextImpl 对象;
ContextImpl appContext = createBaseContextForActivity(r);
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
...
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
...
return appContext;
}
3)调用 Instrumentation
的 newActivity 方法新建并加载 Activity,newActivity 方法中调用 AppComponentFactory 的 instantiateActivity方法,instantiateActivity 方法通过在 performLaunchActivity 方法中新建的 ClassLoader
加载新建的 Activity 类;
activity = mInstrumentation.newActivity(cl,component.getClassName(),r.intent);
//Instrumentation
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
//AppComponentFactory
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
4)通过 LoadApk
的 makeApplication 方法创建一个 Application 对象;
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//r.packageInfo 就是 ActivityClientRecord 中存的 LoadApk 对象
5)调用 Activity 的 attach
方法,ContextImpl 通过 Activity 的 attach 方法来和 Activity 建立关联,除此之外,attach 方法还完成了 Window 的创建并建立自己和 Window 的关联,这样当 Window 接收到外部输入事件后就可以将事件传递给 Activity;
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,
r.assistToken);
//Activity的attatch
//将创建的 Activity 和 ContextImpl
attachBaseContext(context); 建立关联
//为新建的 Activity 创建 Window,用于接收到外部输入事件后将事件传给Activity
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
6)调用 Instrumentation
的 callActivityOnCreate 方法,callActivityOnCreate 方法调用 Activity
的 performCreate 方法,performCreate 调用 onCreate
方法。
mInstrumentation.callActivityOnCreate(activity, r.state);
//Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
//Activity
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
至此走完了从发起启动 Activity 的请求、Activity 的创建、Activity 的加载到最后调用 onCreate 方法的整个流程。这里只是分析整个的流程大概,涉及到启动模式等的细节没有去探讨。
4. 总结
4.1 重要类
- Instrumentation:管理应用进程和系统进程之间的通信;
- ActivityTaskManager:实现应用进程和运行在系统进程的 ActivityTaskManagerService 的通信;
- ActivityTaskManagerService:负责管理activity;
- ActivityStarter:负责启动模式,启动Flag相关处理;
- ActivityStack:负责管理单独栈的 Activity 和其状态,即具体启动的执行等;
- ApplicationThread(IApplicationThread):继承自 IApplicationThread,会在 ActivityTask 中调用,处理 Activity、Service、Broadcast 的创建等操作;
- ActivityThread(ClientTransactionHandler):继承自 ClientTransactionHandler,管理应用进程中主线程,执行和调度 Activity、广播,处理来自 Activity 的任务请求;
- ActivityClientRecord:保存和 Activity 相关的参数信息,还保存了和 Activity 关联的 Window 的信息;
4.2 完整流程图
5. 参考
- Activity 启动流程分析
- 深入研究源码:Activity 启动流程分析
- 《Android 开发艺术探索》