Activity的工作流程
系统内部到底是如何启动一个Activity的呢?
新的Activity对象是在何时创建的?
Activity的onCreate 方法何时被系统回调的呢?
分析Activity的启动流程:
从Activity的startActivity 方法开始分析,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) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
其中mParent 代表的是ActivityGroup,ActivityGroup 最开始被用来在一个界面中嵌入多个子Activity,但是ActivityGroup在API 13中已经被废弃了,系统推荐采用Fragment来代替。
**mMainThread.getApplicationThread()**这个参数,他的类型是ApplicationThread,ApplicationThread 是 ActivityThread 的 一个内部类,通过后面的分析可以发现,ApplicationThread和ActivityThread 在启动过程中发挥着很重要的作用。
接着看Instrumentation 的 execStartActivity 方法。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
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 方法来完成。
可以看出这里和Binder是有关系的。
IActivityTaskManager,我们需要去找到他的实现类,他的实现类是会有一个startActivity方法的。
这个实现类就是ActivityTaskManagerService
我们看看ActivityTaskManagerService 的startActivity 方法
这里它又去调用了startActivityAsUser()。
书上一直的版本一直提及的ActivityManagerService(AMS) 它的startActivity 是转交给了ActivityTaskManagerService 的startActivity来实现的。
startActivityAsUser方法最后执行了一个execute()方法。
obtainStarter 会返回一个ActivityStarter对象,后面是一系列的set方法。
…我迷路了…啊啊啊啊。
我…
个人猜测关键代码应该在刚刚的execute方法中,但是流程有点蒙了。
后面的流程已经蒙了,书上说Handler H 来完成相应的事件,在处理LAUNCH_ACTIVITY的时候,会调用handleLaunchActivity方法,而这个方法会去调用performLaunchActivity方法来完成Activity的对象和启动过程。
performLaunchActivity主要完成了下面几件事
1、从performLaunchActivity中获取待启动的Activity 的组件信息。
2、通过Instrumentation的newActivity 方法使用类加载器创建Activity对象。
3、通过LoadedApk 的makeApplication 方法尝试创建Application对象。(Application创建完毕后,系统会通过Instrumentation 的callApplicationonCreate 来调用Application的onCreate方法。)
4、创建ContextImpl对象并通过Activity 的attach 方法来完成一些重要数据的初始化。
5、调用Activity 的onCreate 方法。(mInstrumentation.callActivityOnCreate()).