安卓binder机制简要

说起binder我们貌似在一个地方用过,就是service中用到的,里面有一个重写的方法onBind,这个方法返回的就是一个binder对象,我们的activity和services就是通过这个binder对象实现通信的,除了这点以外,binder还有一个重要的地方,那就是进程间通信,AIDL正是基于binder机制来实现的,所以搞清楚binder机制是很重要的。

1.要实现夸进程通讯,会采用C/S架构,即客户端服务端模式,这种针对于android进程间通讯的机制就叫做binder机制。针对于这套机制,从大的方面来说,我们把这套机制分成三层:
                 

  java层(上层)         BinderProxy (client)            Binder(server)
                                                |                                                       ^
                                                V                                                       |
                                      -----------------------                       ----------------------------
  native层(中间层)     BpBinder                                    javaBBinder
                                                |                                                       ^
                                                V                                                       |
                                          -----------------------                     ----------------------------
                                                       |                                               ^
                                                       V                                               |

binder驱动层(底层)                               Binder驱动






通过上面这个图表我们看到有三层:java层,native层,binder驱动层,如图表中的箭头所示,当我们开始夸进程通讯的时候,我们的信息会从client端发出,经过client的native层,然后来到了binder驱动,随后这个信息又给到了server的native层,最后在把这个信息给到了server的java层,这样就完成了一个夸进程通讯。疑问来了,这个native层和这个java层是什么关系呢,其实java层的binder架构是native层binder架构的一个镜像,这个镜像最终还是需要借助native层的binder系统来开展工作。

首先,我们先来说说java层中的binder成员,在这一层中定义了两个接口三个类,分别是IBinder接口,DeathRecepient接口,BinderInternal类,Binder类,BinderProxy类。那他们是什么关系呢?
     (1)DeathRecepient接口是在IBinder接口内部定义的一个接口
      (2)Binder类和BinderProxy类implements自IBinder接口
     (3)BinderInternal类相当于binder架构的一个辅助类,例如处理类似垃圾回收这样的工作。
     除此之外,在IBinder接口中还定义了一个叫做FLAG_ONEWAY的整形变量,这个变量的作用是什么呢?在此说明一下,当进行一次跨进程通讯的时候,但我们指明了这个变量后,客户端只需要把请求发送到Binder驱动即可,不用等待服务端的返回结果,这就是一种非阻塞的方式;如果不指明,客户端会一直阻塞,直到有返回结果。

然后,来说一下java层binder框架的初始化,在java层初创时期,系统会提前注册一些JNI函数,有一个函数专门负责搭建Java Binder和Native Binder的交互关系,这个函数是register_android_os_Binder(),这里面总共又调用了三个函数,分别是int_register_android_os_Binder(env),int_register_android_os_BinderInternal(env),int_register_android_os_BinderProxy(env),从这个三个函数的名字可以看出来,他们分别映射了和java层Binder,BinderInternal,BinderProxy的关系,其实就是建立java层对象和与其对应的jni层对象的联系,所谓的注册其实就是获取jclass对象,并且获取有用的methodId,并将获取的methodID保存到相关的Offsets静态类对象中。

下面通过两个例子来说明一下,如何进行进程间通信的,第一个例子是AMS将自己注册到ServiceManager,第二个例子是AMS如何响应客户端Binder请求。
先说第一个:
ActivityManagerService m=self;
通过调用ServiceManager.addService("activity",m);将需要的service注册到ServiceManager中,现在进入到addService()方法中,里面有一个getIserviceManager.addService(name,service);所以先看看getIserviceManager,在这个方法中是一个sServiceManger=ServiceMangerNative.asInterface(BinderInternal.getContextObject());这个方法中的asInterface方法看起来似乎很眼熟,因为在AIDL中经常会见到这个方法,他的参数BinderInternal.getContextObject()是一个native方法,这个方法里面就是创建一个java层的BinderProxy对象,并且将这个对象与一个jni层的BpBinder对象关联,这里面还有一个BpProxy对象,这里面认为BpBinder对象和BpProxy对象就是一个,所以总的来说BinderInternal.getContextObject()方法就是返回一个BinderProxy对象,然后我们通过操纵BinderProxy对象来镜像控制jni层的BpBinder对象,BpBinder对象和BpProxy对象关联,BpProxy对象的通信目标就是ServiceManager.接下来ServiceMangerNative.asInterface(。。。obj)通过组合obj返回了一个ServiceManagerProxy对象(sServiceManger),在调用ServiceManagerProxy对象的addServices()方法,那么接下来我们进入到这个方法里面看看,这里面有两个重要的方法,一个是data.writeStrongBinder();另一个是mRemote.transact();这个mRemote其实就是前面所产生的BinderProxy对象,transact()方法是个native方法,该方法调用之前与之相关联的BpBinder方法的transact()方法,最后总的来说就是调用BpBinder的transact()方法。这样就完成了把请求传递到binder驱动了。那前面说的data.writeStrongBinder()这个方法呢?这个方法其实就是完成了一个替换工作或者说是建立了一种连接,建立了和谁的连接呢,其实就是JavaBBinder和Binder的连接,所以真正传递到binder驱动的就是这个JavaBBinder对象,当驱动收到这个JavaBBinder对象的时候,就会调用他的onTransact()方法,这个方法又会调用与之相关联的java层的binder对象的exeTranscat()方法,这个方法里面又调用了onTransact()方法,这个onTransact()里面会实现具体的业务逻辑。


           
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
千里马8年Android系统及应用开发经验,曾担任过美国unokiwi公司移动端技术总监兼架构师,对系统开发,性能优化,应用高级开发有深入的研究,Android开源定制ROM Lineage的贡献者之一,国内首家线下开辟培训Android Framework课程,拥有2年的Android系统培训经验。成为腾讯课堂专业负责android framework课程分享第一人,致力于提高国内android Framework水平Android Framework领域内是国内各大手机终端科技公司需要的人才,应用开发者都对Android系统充满着好奇,其中的binder是重中之重,都说无binder无Android,binde是Android系统的任督二脉。课程水平循序渐进,由中级再到高级,满足各个层次水平的android开发者。1、灵活使用binder跨进程通信,在app端对它的任何api方法等使用自如2、可以单独分析android系统源码中任何binder部分,分析再也没有难度3、掌握binder驱动本质原理,及对应binder驱动怎么进行跨进程通信,及内存等拷贝方式数据等4、对binder从上层的java app端一直到最底层的内核binder驱动,都可以顺利理通5、针对系统开发过程中遇到的binder报错等分析方法,及binder bug案例学习6、针对面试官任何的binder问题都可以对答自如7、socket这种跨进程通信实战使用8、针对android源码中使用的socket源码轻松掌握9、android系统源码中最常见的socketpair中双向跨进程通信10、使用socket实现一个可以让app执行shell命令的程序

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值