android (八)Binder浅谈
本文主要内容的:
Java层Binder结构,Java层Binder调用的信息流,Native层Binder的框架结构,Native层Binder调用信息流向。
在这里写下对binder的理解,说到Binder间进程通信,Linux那么多进程间通信工具为何引入了Binder。大概原因有两点:
1、为了提高通信的效率。
2、为了方便开发者,让进程间通信和本地调用一样简单方便。
Binder无处不在,日常开发中无形中一直在用Binder进行通信,例如Activity的创建,窗口的显示等等。
Java层Binder:
具体的应用比如说:ActivityThread中的ApplicationThread就是继承了IBinder,这里的IBinder是java层的binder。那么Java层的binder都做了什么的事呢,看过java层的binder的源码后,发现并没有想象中的复杂,只是java通向native的接口;Java层的binder是调用了c++的Binder实现。
Binder分为两大部分:Binder应用和Binder驱动。
Binder应用层分为Java层和native层,外加一个Java和native通信的接口层;android_util_Binder.cpp作为java和native之间接口层。
举例说明ActivityThread中的Binder创建过程,ApplicationThread是ActivityThread中的内部类,主要负责与内核进行通信。
private class ApplicationThread extends ApplicationThreadNative
public abstract class ActivityManagerNative extends Binder implements IActivityManager
这样ApplicationThread 就是Binder的子类,ApplicationThread 创建对象的时候会调用Binder的构造方法。java层的binder的构造方法中调用了一个叫init的本地方法。
public Binder() {
init(); 省略部分代码
}
android_util_Binder.cpp中的init方法主要是创建了JavaBBinderHolder指针, JavaBBinderHolder主要用来管理JavaBBinder实例,JavaBBinder为BBinder的派生类,BBinder为native层的Binder实现。
static void android_os_Binder_init(JNIEnv* env, jobject clazz)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh);
jbh->incStrong(clazz);
env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);
}
java层各个部件之间的互相协作图
Native层Binder:
- IBinder、BBinder、BpBinder:IBinder是对android binder的抽象,它同时具有BBinder和BpBinder两个子类。BBinder负责接收RPC代码和数据并在Binder Driver内部生成Binder节点。BpBinder保存有目标服务的Handler信息,用于在Binder Driver中Binder节点的查找。
- IPCThreadState负责与Binder Driver通信。
- IInterrace 、 BnInterface 、 BpInterface : IInterface 类提供类型变换功能,将服务或服务代理类转换为 IBinder 类型。实际的类型转换是由 BnInterface 、 BpInterface 两个类完成, BnInterface 将服务类转换成 IBinder 类型,而 BpInterface 则将服务代理类转换成 IBinder 类型。在通过 Binder Driver 传递 Binder 对象时,必须进行类型转换,比如在向系统注册服务时,需要先将服务类转换成 IBinder ,再将其传递给 ServiceManager 。
- Processstate 、 IPCThreadstate : Processstate 类用来管理 Binder Driver , IPCThreadstate 类用来支持服务客户端、 Service Server 与 Binder Driver 间的 Binder IPC 通信。
- Parcel :在服务与服务代理服务进行 Binder IPC 时, Parcel 类负责保存 Binder IPC 数据。 Parcel 类可以处理的数据有 C 语言的基本数据结构和数组、 Binder 对象、文件描述符等。
服务的框架大致分为三层服务层、RPC层和IPC层;在开发服务时需要实现的有服务层中的服务接口、服务类,以及 RPC 层中的服务代理和服务 stub 。
- 服务层: Ilnterface、 Bnlnterface 、 Bplnterface 、 BpRefBase 、服务接口、服务类 。
- RPC 层:服务代理类、服务 stub 类 。
- IPC 层: BBinder、 BpBinder 、 IPCThreadstate、 Processstate、 Parcel。
本地服务的信息传递,可以用这么一幅图来描述,层次比较清晰,方便理解Binder的工作流程。
AudioFlinger音频服务类图如下
·