android (八)Binder浅谈

 本文主要内容的:

 

       Java层Binder结构,Java层Binder调用的信息流,Native层Binder的框架结构,Native层Binder调用信息流向。

     在这里写下对binder的理解,说到Binder间进程通信,Linux那么多进程间通信工具为何引入了Binder。大概原因有两点:

 

1、为了提高通信的效率。

2、为了方便开发者,让进程间通信和本地调用一样简单方便。

 

        Binder无处不在,日常开发中无形中一直在用Binder进行通信,例如Activity的创建,窗口的显示等等。

Java层Binder:

      具体的应用比如说:ActivityThread中的ApplicationThread就是继承了IBinder,这里的IBinderjava层的binder。那么Java层的binder都做了什么的事呢,看过java层的binder的源码后,发现并没有想象中的复杂,只是java通向native的接口;Java层的binder是调用了c++Binder实现。

 

      Binder分为两大部分:Binder应用和Binder驱动。

      Binder应用层分为Java层和native层,外加一个Javanative通信的接口层;android_util_Binder.cpp作为javanative之间接口层。

     举例说明ActivityThread中的Binder创建过程,ApplicationThreadActivityThread中的内部类,主要负责与内核进行通信。

 

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音频服务类图如下

·

 

posted @ 2016-07-20 17:50  清澈见底  阅读(211)  评论(0编辑  收藏  举报