回顾 01. APP 进程启动和 ActivityThread 的关系 知道 Activity 被创建后会执行 attach() 方法。这个方法会把当前的 ActivityThread 实例和 Instrumentation 实例关联给新创建的 Activity。
查看 activity.startActivity 源码
首先我们从 startActivity() 看起,无论怎么样,最终都会走到这里。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
// 这里才是执行启动Activity
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());
}
// 省略一些代码.....
}从上面代码可以看出 mInstrumentation.execStartActivity 才是真正的执行启动 activity; 再看下源码
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 省略一些代码 .....
try {
// 这里启动 startActivity
int result = ActivityManagerNative.getDefault()
.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;
}我们可以看到ActivityManagerNative.getDefault()这个才调用 startActivity 的地方;
然后我们再去看下 Instrumentation 这个类,我们就会发现有很多 callActivityOnXXXX 方法,从方法名不难看出,这些主要是 activity 的生命周期方法管理,真正调用还是在 ActivityThread 里面;
ActivityManagerNative.getDefault()
查看一下 ActivityManagerNative.getDefault() 是个什么;
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
// 获得一个 IBinder
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;
}
};
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// 再次查询了一遍,跨进程查询
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
// 跨进程查询不到,就本地做一个代理
return new ActivityManagerProxy(obj);
}从以上 2 端代码可以发现主要是想获得IActivityManager, 这个对象主要是在 ServiceManager 中获得的一个 IBinder, 如果本地没有就生成一个代理;
这里需要说明一下IBinder 是跨进程访问的;至于是为什么,以后再说;
这里列举一下几个关键类;
- Activity
- ActivityManagerNative
- IActivityManager
- ServiceManager
- IBinder (跨进程访问主要桥接类)
- ActivityManagerProxy
我们从简单的 activity.startActivity 出发。查看了想要启动下一个 Activity 的时候必须经过一下几步的关键路径;
--> mInstrumentation
--> ActivityManagerNative.getDefault()
--> Binder obj = ServiceManager.getService("activity")
--> IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor)// 这个其实是个跨进程查询
如果查询不到,就在 app 进程代理出一个 IActivityManager (ActivityManagerProxy)
-->in.startActivity()
-->mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);以上是对启动一个 activty 到把相关参数传递到Binder.transact 的整个过程(切记这里就开始跨进程调用了); transact(START_ACTIVITY_TRANSACTION, data, reply, 0);这里的 data 包含了很多 Intent 和 activity 的相关信息;为了让文章看起来不是很累就先把当前进程里面的先捋清楚,关于跨进程先不说;
其他结论
android.os.ServiceManager 是 framework 中的类;需要下载 framework 代码查看一下不难发现 ServiceManager 有个 HashMap;
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
//.... 省略代码...
// 看的出来ServiceManager.getService("activity");
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}ServiceManager 把 ActivityManager 管理在这个缓存里面,所以应该有很多其他的IBinder (也有可能是其他的Manager,以后展开)
疑问
当 startActivity 后
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); 这个地方执行到哪里去了,怎么样启动 activity 让它展示呢??从目前来看,应该还没有创建 activity 的 Window 吧?
第 1 个问题: mRemote.transact 到这里,其实他已经执行到其他进程去了,本地代码其实只是个代理;
第 2 个问题: 其实真正创建 Activity 的 window 应该是在 ActivityThread 的 performLaunchActivity() 里面,但是怎么过来呢??还记得 ActivityThread 里的 Looper 吗?那里一直在循环着呢,他其实在哪里等消息呢,只要Looper接收到 Message 就可以处理 performLaunchActivity 了,到底是怎么接收呢? ActivityThread 有个private class H extends Handler这个类;具体流程就等下一篇再叙说吧。我不喜欢一篇写的太长了