Activity的启动过程第二篇
首先,还是先将总体的顺序写出来
1、Laucher组件 首先向AMS(AndroidManagerService)发送一个启动Mainactivity的请求, 这个请求是进程间通信的。
2、AMS首先将要启动的MainActivity组件的信息保留起来,然后向Laucher组件发送一个进入终止状态的进程通信。
3、然后,Laucher组件会接收到AMS发来的中止请求,进入中止状态, 然后再向AMS发送消息,告诉AMS 我已经进入中止状态了,你请继续做你的是事情,这样AMS就能继续进行启动Aty的操作。
4、由于MainAty的启动是在Lauther程序中启动的,Lauther中止了,程序应用进程也就不存在了,然后AMS就会新启动一个应用进程。
5、新的应用进程启动后,就会告诉AMS 我(新的应用进程)已经启动好了,然后发一个通信请求给AMS。
6、接收到新应用进程发来的通信后,AMS就会把第二步保留的组件信息 传递给新的进程,然后新的进程就可以靠这些信息去启动MainAty。
上一篇启动过程分析完了第一步,这一篇来分析第二步。也是先放源码。
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
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;
}
final View decor = mWindow != null ? mWindow.peekDecorView() : null;
if (decor != null) {
decor.cancelPendingInputEvents();
}
// 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);
}
}
}
我们单独把这段代码拿出来分析
if (mParent == null) {
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());
}
可以看到,这里面调用了Instrument类,并且执行了execStartActivity()这个方法。
我么先简单了解一下这个Instrument类的作用。
Instrument类的主要作用:他用来监控,应用程序和系统之间的交互操作。
OK,现在可以看一下里面的参数,有一个mMainThread.这个mMainThread是Activity的一个成员变量ActivityThread,系统每打开一个应用,都会初始化一个ActivityThread的实例,并且传给每个应用的父亲Activity(这个父亲Activity就是我们的每一个继承的Activity),然后看一下mMainThread.getApplicationThread()这个,好的 ,看一下ActivityThread的源码里面这个方法。
public ApplicationThread getApplicationThread()
{
return mAppThread;
}
返回的是一个mAppThread,这个Application其实就是一个IBinder的本地对象。有兴趣的道友可以看一下源码,会调用mAppThread.asBinder方法,可以验证这一点。这个mAppThread对象可以和Launcher通信,在执行了execStartActivity()之后就会通过binder通知Launcher进入停止状态。
在这里,作者罗老师强调了一个地方,就是这个mToken,查看源码知道,这个mToken是个IBinder类型的成员变量,他是一个IBinder的代理对象,指向了,AMS中,一个类型为ActivityRecord的本地对象。每一个启动的Activity组件,在AMS中都有一个对应的ActivityRecord的对象,这个ActivityRecord对象,是用来维护对应的Activity的运行状态以及信息。
到这个地方,第二部就完成了。
OK 继续深入execStartActivity()这个方法。先看源码
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//主要过程放在IApplication中执行
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
//这里查找Activity 是否存在
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//这里是真正打开Activity的地方
//这个ActivityManagerNative.getDefault()是AMS的代理对象,调用startActivity来将activity启动起来
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
我们着重看这段代码
//这里是真正打开Activity的地方
//这个ActivityManagerNative.getDefault()是AMS的代理对象,调用startActivity来将activity启动起来
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
可以看到,在execStartActivity里面,调用了ActivityManagerNative.getDefault(),那这个ActivityManagerNative.getDefault()返回的是什么呢?看一下源码。
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
这个返回的是一个IActivityManager对象,这个IAM 实际上是AMS(AndroidManagerService)的代理对象,然后通过调用它的startActivity来通知AMS将一个Activity组件启动起来。
第二篇先写到这里,一点一点消化。