ActivityManagerService与应用进程间的通讯

  1. 说明: 基于API 25的源码分析, 以系统进程ActivityManagerService和应用进程间通讯为例

    1.类图

    class_ipc

    ActivityManagerNative: 抽象类

    ActivityManagerService:在系统进程,ActivityManagerNative的实现类。

    ActivityManagerProxy: 运行在应用的进程调用, 用于调用系统进程的方法

    ApplicationThread: 是ActivityThread的一个内部类,是ApplicationThreadNative的实现类。

    ApplicationThreadProxy: 运行在系统进程中,用于系统进程调用应用进程的方法。

    从上图看可以知道,上,下两个图结构是一样的,ActivityManagerService和ActivityManagerProxy实现同一个接口IActivityManager; ApplicationThread和ApplicationThreadProxy实现同一个接口IApplicationThread。IActivityManager和IApplicationThread都实现IInterface, 而且被调用的一方必须继承Binder,继承Binder的好处就是实现IInterface的asBinder方法时,返回this就可以了。

    2. 源码分析

    说明: 在下面的文章里,ActivityManagerService简称AMS; ActivityManagerProxy简称AMP; ActivityManagerNative简称AMN。

第一步: 从ActivityThread的attach方法开始分析

attach方法是在ActivityThread的main方法入口里调用的,先看看attach的源码:

ams_ipc_01

调用ActivityManagerNative.getDefault()获取IActivityManager,实质上是AMP。

mAppThread是ApplicationThread一个实例,调用mgr.attachApplication(mAppThread)是一次跨进程通信,mAppThread作为参数传给AMS的进程,AMS就可以调用应用进程的方法,从而实现了进程间相互通讯。

2.2 第二步: 看看ActivityManagerNative.getDefault()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    /**
* Retrieve the system's default/global activity manager.
*/
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;
}
};

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);
}

gDefault是一个单例,单例的实例在create方法里创建,调用ServiceManager.getService(“activity”)获取到IBinder一个对象,这个对象实质是BinderProxy类型,BinderProxy实质又是代理了AMS。最后调用asInterface方法创建了一个AMP实例。

2.3 第三步:跟踪 mgr.attachApplication(mAppThread)

根据前两步分析,可以知道mgr是AMP,看看AMP的attachApplication方法:ams_ipc_02

mAppThread继承Binder,同Parcel的writeStrongBinder()把mAppThread写到parcel中,由第二步可以知道mRemote是一个BinderProxy,通过调用transact方法把parcel传到另一进程。ATTACH_APPLICATION_TRANSACTION是一个int类型,是一个flag用于区分类型的。接着会调用binder的onTransact(),这个binder是AMS,AMS继承AMN, onTransact的实现在AMN。

第四步 ActivityManagerNative的onTransact()

ams_ipc_03

看蓝色强调的代码,data是一个parcel对象,data.readStrongBinder()获取应用进程传过来的IBinder,通过ApplicationThreadNative的asInterface方法获取IApplicationThread实例,IApplicationThread这个实例实质就是ApplicationThreadProxy。data.readStrongBinder()获取到应用进程传过来的IBinder本质是也是BinderProxy实例。有了ApplicationThreadProxy就可以调用应用进程的方法了。ApplicationThreadProxy的跨进程调用原理跟AMP的原理一样的。

3. 总结

跨进程的步骤可以归纳为:

  1. 定义一个统一的跨进程接口, 暂且命名为IPC,这个接口实现IInterface
  2. 调用进程和被调用的进程双方都需要IPC, 被调用的进程方需要继承Binder, 调用进程方是一个代理,持有一个IBinder, 通过IBinder的transact方法,去触发被调用的进程方的onTransact方法;
  3. 进程间的数据传递通过Parcel类
Loading comments box needs to over the wall