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。

 

 

 

转载于:https://www.cnblogs.com/zhangxinyan/p/3487879.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
main SpringApplication.java:771 - Application startup failed org.springframework.context.ApplicationContextException: Failed to start bean 'inputBindingLifecycle'; nested exception is org.springframework.cloud.stream.binder.BinderException: Exception thrown while starting consumer: at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:50) at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:348) at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:151) at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:114) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:880) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) at com.migu.rstone.UserCenterApplication.main(UserCenterApplication.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) Caused by: org.springframework.cloud.stream.binder.BinderException: Exception thrown while starting consumer: at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindConsumer(AbstractMessageChannelBinder.java:258) at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindConsumer(AbstractMessageChannelBinder.java:57) at org.springframework.cloud.stream.binder.AbstractBinder.bindConsumer(AbstractBinder.java:145) at org.springframework.cloud.stream.binding.BindingService.bindConsumer(BindingService.java:97) at org.springframework.cloud.stream.binding.BindableProxyFactory.bindInputs(BindableProxyFactory.java:221) at org.springframework.cloud.stream.binding.InputBindingLifecycle.start(InputBindingLifecycle.java:55) at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:175) ... 22 more Caused by: java.lang.IllegalArgumentException: A list of partitions must be provided at org.springframework.util.Assert.isTrue(Assert.java:92) at org.springframework.cloud.stream.binder.kafka.KafkaMessageChannelBinder.createConsumerEndpoint(KafkaMessageChannelBinder.java:241) at org.springframework.cloud.stream.binder.kafka.KafkaMessageChannelBinder.createConsumerEndpoint(KafkaMessageChannelBinder.java:88) at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindConsumer(AbstractMessageChannelBinder.java:217) ... 28 more 报错解决办法
07-15

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值