Binder机制一直是Android面试的一个难点,尤其是Binder驱动,那不是一篇文章就能简单说清楚的,本篇还是一样,作为面试复习的一个支撑,阅读如果出现不懂的,需要及时查阅相关资料。
1、Linux内核基础知识
2、什么是Binder
Android作为移动端操作系统,传统的Linux进程间通信机制不满足于Android,所以开发了一套新的IPC机制,就是Binder机制。
3、为什么Android使用Binder机制
Linux 本身就支持很多通信机制,比如 Socket,管道,共享内存。选择Binder机制主要有以下2个原因
4、Binder机制通信模型
Binder的通信机制有4个重要角色:Client、Server、Binder驱动、ServiceManager。
Client、Server、ServiceManager都在用户空间,处于不同进程。Binder驱动位于内核空间,ServiceManager相对于通讯录,内部保存了Server相关的信息,这样Client就可以通过ServiceManager拿到Server的信息,Binder驱动就相当于通信基站,这样Client和Server直接就可以通信了。
5、Binder机制通信原理
结合以上通信模型,可以看出Binder通信机制分三步:
第一步:ServiceManager在其内部维护一张表;
第二步:服务端进程向ServiceManager注册信息;
第三步:客户端进程向ServiceManager取得信息,通过Binder驱动与服务端进程通信;
这里我们一直在强调通过Binder驱动进行通信,那么Binder驱动究竟是如何进行通信的
如上图,Client想调用Server的的add方法,该方法返回一个Object对象。
首先,Server会先向ServiceManager注册一张表,这个表中就存储了相关信息,告诉ServiceManager我这里有一个返回值为Object的add方法,client向ServiceManager中查询Server端有没有一个返回值为Object的add方法,由于进程之间的通信都是在内核中进行的,驱动会在数据传输时做一些手脚,不会返回给client真正的server的Object的对象,而是返回一个代理对象,这个代理对象里包含了一个add方法,要注意,代理对象的add方法是一个空方法,它唯一要做的只是需要将参数包装好之后交给Binder驱动来实现。
Binder驱动收到代理对象的add方法之后,会在ServiceManager表中查询存在有这个方法,Binder驱动就会将代理对象替换成server端的对象,调用server端的add方法,最后将结果返回给Client。
6、AIDL是什么?与Binder的关系
AIDL(Android Interface definition language),从名字可以看出,它是一个Language,所以它并不是Android的跨进程通信机制,它只是我们程序员偷懒的一个工具,真正的进程间通信,还是Binder来实现的,AIDL只是帮我们生成Binder和BinderProxy接口类,只要你愿意,完全可以不创建AIDL文件,自己实现这一套代码。
7、AIDL使用步骤
①新建AIDL文件,例如IMyAidlInterface.aidl,内部声明一个add方法
②然后我们只需要点击 Build -> Make Project,等待构建完成,AS就会自动为我们生成复杂的Java文件。在build\generated\aidl_source_output_dir\目录下,会生成一个IMyAidlInterface.java文件继承自IInterface,并且内部生成了一个抽象静态内部类Stub
可以看到,Proxy已经实现了add方法,那我们为什么还要怎么实现自己的业务逻辑呢?其实在Proxy的构造方法中,传入了一个IBinder对象,保存为成员变量mRemote,这里的add实现,其实是调用了mRemote的transact方法,将请求发送到了真正的服务端来实现,那么Proxy是在哪里被调用的,经过查看,是在Stub类的asInterface方法中
这里面的逻辑是,如果当前是Server端自己调用,那么直接返回Binder对象本身,否则,返回一个代理对象Proxy, 这里也印证了前面的理论,客户端拿到的其实是代理对象,并不是直接与服务端交互。
③有了这些系统帮我们生成的通信基础的代码,我们只需要关心服务端和客户端就好了,接下来创建服务端代码MyAidlService.java,并在Manifest文件将其声明在另一个进程
④客户端通过bindService()来绑定服务端的时候,我们返回了Binder,也就是之前的stub对象,这里才是实现我们自己的业务逻辑。
⑤客户端通过bindService中的ServiceConnection拿到IBinder对象后,就可以通过IMyAidlInterface.Stub.asInterface(service)转换为我们的服务端AIDL类(代理类),从而实现进程间通信。
好累,差点把自己都绕晕了
就到这吧
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有