binder学习笔记(二)

上一篇对binder大概介绍了下,并且写了一个用binder跨进程的范例。接下来我将对AIDL生成的java文件结合binder驱动讲解下。 

由上一篇的范例可以看到,客户端通过bindService启动服务端组件Service,组件service通过Binder mBinder = new IBookManager.Stub()生成了binder的实体对象,客户端和服务端建立连接后,就可以通过onServiceConnected获得这个binder的引用对象了,获得引用对象后,就要把这个对象转换成客户端所需的AIDL接口类型的对象。

IBookManager bookManager = IBookManager.Stub.asInterface(service);

asInterface就是实现这个转换的。当客户端和服务端位于同一个进程,那么此方法返回就是服务端的Stub对象本身,否则返回式系统封装后的Stub.proxy这个代理对象。用形象的说法,在跨进程中,客户端是和它里面的代理对象进行通信,而这个代理进行再和服务端通信,就相当于客户端和服务端进行了通信,而这个通信就仿佛是在客户端这一个进程中进行的。

那么客户端到底怎么得到服务端的binder引用对象的呢?这得靠binder驱动了。应用层和binder驱动双向数据传输时通过ioctl()实现的。然后,我们得明白Biner调用的参数传递是通过Parcel类完成的,这就是之前那个Book这个对象要进行继承Parcelable进行Parcel打包了。服务进程会将binder实体对象加入到Parcel对象中进行数据打包,这个数据类型被标记为BINDER_TYPE_BINDER,标示其为实体对象,通过ioctal()把数据传送给binder驱动后。binder驱动会查找其里面该服务进程的“Binder实体对象表”,如果这个实体对象表没有这个实体对象的记录,那么创建新的节点保存这个实体对象信息,然后binder驱动再去看其里面该客户进程的“binder对象引用表”,如果没有这个表中没有该实体对象的引用对象记录,就在表中创建一个新的节点,并使这个节点指向服务进程的“binder对象实体表”的节点。然后binder驱动将数据类型标记为BINDER_TYPE_HANERL,用来表示它为引用对象。其中数据中有一个handle值,这个值就作为“binder对象引用表”中该引用对象的节点序号,上一篇介绍到ServiceManager时,它的handle就被硬性设置为0了。最后被改动的数据传送到了客户进程。

客户进程接收到数据后,发现数据是BINDER_TYPE_HANEL后,取出其中的handle值去再调用ProcessState类里面一个函数得到binder引用对象。简单介绍下ProcessState类,每个进程只有一个ProcessState,它做了两件事,一个打开binder设备,另外是调用mmap()在驱动中分配了一块内存空间,用于binder驱动接收传递给进程的binder数据,这块内存是内核和进程共享。普通IPC传递数据时,数据先从进程空间复制到内核,再从内核复制到另一个进程空间中。而在binder机制中就不需要复制两次了,因为每一个用户进程有一块内存是和内核共享的,这样,从某一个用户进程发送的数据,内核直接从这个共享内存中取出数据然后复制到另外一个进程和内核共享的内存中,这样就数据传递就只复制了一次,提高了效率。

自此,binder机制的大概流程基本讲完了,最后补充一些知识点。服务进程中binder调用的执行,每次执行都是在binder线程池中进行的。在binder的设计中,binder线程池的第一个线程是应用层主动创建的,其他的线程都是在binder驱动的请求下才创建的。这是为了防止binder调用太多,线程创建过多,从而binder驱动来控制线程的数量。当客户端进行binder服务调用时,客户端会挂起一直等待服务端返回结果。由于可能任务耗时过长,客户端会出现ANR,这种情况我们必须得考虑到。所以上一篇的范例中在主线程中等待获取book信息是不合理的,可能导致ANR,范例这样写只是更好的了解AIDL的实现步骤。 另外,若想更深入了解binder细节。看任玉刚的《Android开发艺术探索》和刘超的《深入解析Android 5.0系统》是极好的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值