• Binder机制,从Java到C (6. Binder in Native : libbinder)


    1.Java和C++中的Binder

    从前一篇 Binder机制,从Java到C (5. IBinder对象传递形式) 中可以看到,使用Binder的Java代码,到最后都会进入到Native环境,将具体的分发工作交给执行效率更高的Native代码。
    而这些Native的实现都会统一到一个lib:libbinder
    在前面的讲述中,我们已经接触到了native中的JavaBBinder,BBinder,JavaBBinderHolder

    把一些相关的类整理一下,可以得到下面Java和C++代码的关系:

    Java环境里的Binder的对象,会通过JNI 调用init()方法,创建一个JavaBBinderHolder,从而使自己映射到Native环境里的BBinder。将两个环境里的Binder对象映射在一起。

    2.transact()
    BinderProxy中的transact()是以JNI的方式实现的,那它就是Java层和C++层的沟通纽带,Java通过它可以进一步和native交互。

    Java环境里的的Binder,有一个private 的execTransact()方法,其实就是Native环境的callback,也就是C++层回到Java层的一个入口。

    JNI代码在执行Native环境的onTransact()方法時,会通过回调Java环境里的execTransact()方法,从而回调到Java里实现的onTransact()方法。

    3.libinder

    Binder在Java环境中大量使用了面向对象的重构技巧,尽可能的实现通用操作。于是,为了支持给Java环境提供的灵活功能,在Native层的Binder,也需要具备面向对象的能力。libbinder的文件路径:
    /framework/native/include/binder/
        Binder.h
        BinderService.h
        BpBinder.h
        Ibinder.h
        IInterface.h
        IPCThreadState.h
        IpermissionController.h
        IserviceManager.h
        MemoryBase.h
        MemoryDealer.h
        MemoryHeapBase.h
        Parcel.h
        PermissionCache.h
        ProcessState.h
    /framework/native/lib/binder/binder/
        Binder.cpp
        BpBinder.cpp
        Iinterface.cpp
        Imemory.cpp
        IPCThreadState.cpp
        IpermissionController.cpp
        IserviceManager.cpp
        MemoryBase.cpp
        MemoryDealer.cpp
        MemoryHeapBase.cpp
        Parcel.cpp
        PermissionCache.cpp
        ProcessState.cpp
        Static.cpp

    为了能映射Java代码,C++实现的Binder库会和Java环境里的Binder概念有相似互通之处:

    IInterface.h,定义IInterface接口类。与Java的IInterface接口类对应,但与Java环境不同,C++环境里需要提供Binder通信实现,所以在内部被进一步拆分成BpInterface(Proxy端对象)、BnInterface(Stub端对象)两个模板,从而使用不同模板参数,可以使用对同一IInterface接口的访问,得到不同功能实现。

    IBinder.h,定义IBinder接口类。与Java环境的IBinder对应,提供Binder引用,并定义Binder对象所应实现的方法。跟Java环境一样,IBinder对象会是分别引用到Proxy对象或是Stub对象。

    Binder.h,定义BBinder类。BBinder类与Java环境里的Binder类对应,是Binder的Stub实现,通过onTransact()回调方法接收与处理Binder事件。但它更属于Binder通讯的基础类,并不会被直接使用,系统只会通过BBinder类的派生类进行通信,所以它的类名是BBinder,Base Binder的意思。

    BpBinder.h,定义BpBinder类。与Java环境里的Stub.Proxy对象对应,是Binder的Proxy端实现。作为Proxy端,又是Binder最底层的封装,这一类的本质作用只是提供一个transact()方法,从而给上层封装的IPC请求提供最终的Binder通信接口。

     Parcel.h,定义Parcel类。虽然概念上与Java里实现序列化的Parcel类是对应的,也提供同样的操作方法。但在实现上,Native环境里的Parcel是提供Java环境里的Parcel概念的一种基础,所有的Parcel的read|write_*()系列的方法,底层全是由Native代码来实现具体的读写操作。

    4.Binder通信类

    那有了Binder通信封装的类,如何操作Binder 驱动來通信呢?
    在libbinder里,有两个专门的类來完成真正的Binder消息的读写操作 : ProcessStateIPCThreadState


    ProcessState.h,定义ProcessState类。正如这个类的名字所表述的,这个类的作用就是维护和IPC相关的process state,对于任一使用Binder的进程而言,进程空间里只会有一个ProcessState对象。

    IPCThreadState.h,定义类IPCThreadState。这个类描述以thread为基础的IPC传输状态,Binder通信的读写过程便在这个类里完成。在IPCThreadState里,是以thread pool的方式來维护Binder的通信請求。

    下面这个图就是整个通信的流程,蓝色部分是在Java里的,Java中通过BinderProxy的JNI调用,进入到Native层,然后通过IPCThreadState的talkwithDriver()和Binder驱动通信,Binder驱动在做了一系列处理后,找到目标进程,也是从talkwithDriver()方法回去,然后走到JavaBBinder的transact(),这里就会去调用进入Java层的入口函数execTransact()。再回到具体的执行函数

    5.辅助类

    libbinder里会实现一些C++环境里的辅助类:


    Imemory.h,生成两个远程接口类,IMemoryIMemoryHeap,分別用于使用内存和分配内存。对于內存使用两个基于IBinder的接口类,就意味着申请內存和分配內存可以分別由单独的process來提供。

     MemoryDealer.h,定义一个默认的分配內存的MemoryDealer类。在这个类里有一个简单的內存管理算法,需要提供內存分配部分的时候,可以使用这个类來创建內存空间,并通过IMemoryHeap共享出去。

    MemoryBase.h,提供IMemory接口类的Stub端實現。这个类是用在使用内存上的,可以通过它的getMemory()的方法返回一個IMemoryHeap实例。这个类是个基类,如果要使用IMemory接口,可以继承这个类。

    MemoryHeapBase.h,提供IMemoryHeap接口类的Stub端。用于远程共享的堆空間分配,根据不同的情况分配不同类型的內存。

    MemoryHeapPmem.h,实现基于Pmem机制(为了实现共享大尺寸连续物理內存而开发的一种机制)并实现了IMemoryHeap接口。如果有特殊內存堆的使用需求,可以通过MemoryHeadBase类派生出新的MemoryHead类,就像这个MemoryHeapPmem。

  • 相关阅读:
    const 深悟理解
    深拷贝与浅拷贝深究
    结队开发-最大子数组
    软件工程个人作业02
    四则运算关于加括号的思路
    实践出真知-所谓"java没有指针",那叫做引用!
    写代码的好习惯—先构思
    团队合作
    阿超超的四则运算 想啊想啊
    Github+阿超运算
  • 原文地址:https://www.cnblogs.com/zhangxinyan/p/3487879.html
Copyright © 2020-2023  润新知