当我们调用startActivity()启动一个Activity的时候,首先他会调到startActivityForResult()方法:
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
接下来看看 startActivityForResult()里都干了些什么:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {//只要关心mParent==null的情况就可以了
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
.........
} else {
......
}
}
可以看到 startActivityForResult()里调用了 mInstrumentation.execStartActivity(),并且里面有个参数mMainThread.getApplicationThread()【其实就是ApplicationThread】,我们知道启动Activity最重要的其实就是客户端跟AMS通过Binder机制进行通信,所以客户端这边需要获得服务端AMS的代理(具体见下文),然后就可以调用AMS的方法,那么AMS是怎么调用客户端这边的方法呢?客户端的ApplicationThread(ActivityThread的内部类)是一个Binder,而在调用AMS方法的时候它被当做一个参数传过去了,这样子AMS也就获得了客户端这边的Binder代理。这样客户端和服务端这边就可以自如的进行通信,调用了。(Binder机制)
当然上面的这段只是简要的阐述了一下,接下来继续分析整个过程,先看看mInstrumentation.execStartActivity()里面做了什么:
这个里面其实就是获取AMS的代理(Binder机制),然后调用AMS里面的startActivity()方法。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
......
try {
//ActivityManagerNative.getDefault()实际返回的是一个ActivityManagerProxy对象,也就是AMS的代理
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
IBinder b=ServiceManager.getService("activity");
然后转化为AMS代理:
IActivityManager am=asInterface(b);
这样子就获得了AMS的代理。
接下来就看看AMS里面的startActivity()里面做什么:
AMS的startActivity()里面辗转调了好几个函数,最后调到realStartActivityLocked(),这个函数里面有一段代码:
app.thread.scheduleLaunchActivity(),并把AMS这边对这个Activity的记录各方面信息当做参数,这样客户端就能获取到Activity的各种信息即ActivityClientRecord
而这个app.thread的类型是IApplicationThread,而这个接口的实现者就是Activity里的ApplicationThread,而我们知道AMS里面已经获得客户端的ApplicationThread代理,所以他可以调用客户端ApplicationThread里面的scheduleLaunchActivity(),这样子,从服务端又回到了客户端中来了。
接下来看看Applicationthread.scheduleLaunchActivity()里面做了什么:
用一个Handler传一个消息到UI主线程,也就是ActivityThread
然后在Handler中接收消息,并调用handleLaunchActivity()【到了UI线程】。
handleLaunchActivity()中又调用了performLaunchActivity(),performLaunchActivity()里面最终完成了Activity的创建和启动过程。
而performLaunchActivity()里面主要干了一下几件事:
1.从ActivityClientRecord中获取待启动Activity的组件信息(ActivityClientRecord是刚刚AMS服务端调用前端的scheduleLaunchActivity()方法的时候当做参数传回来的)
2.创建Activity对象,通过Instrumentation的newActivity:
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
即通过ClassLoader来装载类并实例化对象。
3.通过LoadedApk的makeApplication方法来创建Application
4.创建ContextImpl对象,并通过Activity的attach()来完成一些重要的数据的初始化,并在这里面创建这个Activity对应的Window,并把这个Window和Activity建立联系,这样当Window接收到外部输入事件后就可以将事件传递给Activity。
5.调用mInstrumentation.callActivityOnCreate(),这里面调用了Activity的onCreate(),至此Activity正式启动。
下面简单总结一下:
先是从客户端开始:
startActivity()-->startActivityForResult()-->mInstrumentation.execStartActivity()
到服务端AMS:
然后在mInstrumentation.execStartActivity()里面获取到AMS的代理(Binder机制),然后就到了服务端
AMS的startActivity()-->一系列辗转调用-->realStartActivityLocked()
然后在realStartActivityLocked()里通过客户端代理ApplicationThread来调用客户端的方法(BInder机制)
再回到客户端:
ApplictionThread里的scheduleLaunchActivity()-->handleLaunchActivity()-->performLaunchActivity()。
上面基本上就是Activity启动的全过程了。