- 名词
- binder是什么
- binder 作用是什么?
- 为什么使用binder,而不使用Linux中的其他通信方式
- binder中有哪些角色?
- Binder中的线程
- Binder通信过程中的内存拷贝
- binder数据数据相关
- Binder使用
- Binder死亡通知
- 参考:
Binder是什么?这个是面试中最长见的问题,请问你如何回答?这里就有你要的答案。
名词
- RPC(Remote Procedure Call Protocol) 远程过程调用协议
- IPC 进程间通信协议
binder是什么
Binder是android中的一种IPC(进程间通信)方式。Binder采用C/S架构。
binder 作用是什么?
作用是完成进程间通信,实现不同进程间的数据共享。
为什么使用binder,而不使用Linux中的其他通信方式
linux还有其他很多种通行方式,如内存共享,Socket、管道、消息队列、管道等。
原因:
- 1、Binder是一种非常简单的进程间通信接口,应用开发者只需要简单的实现AIDL的固定接口就可以完成进程间通信。
- 2、除了Socket支持双向通信外,管道、消息队列、共享内存都不支持双向通信。SOcket虽然支持双向通信,但传输效率低下,开销大,主要用在跨网络进程通信和本机进程间的低速通信。
3、Binder安全性高。
其他IPC方式无安全措施,安全完全依赖上层协议保证。协议数据包在传输过程中的唯一识别码也较容易在通信过程中被篡改。而Android为每个安装应用分配一个独立的UID,可通过UID对进程做校验、鉴别。
binder中有哪些角色?
Binder中有四种角色:
Binder驱动
运行于Linux的内核空间(Kenel space),是进程通信的核心。
ServiceManager
此处的Services是指native层的服务。
ServiceManager自己也是一个Service,由Init进程创建。对于自定义的Service来说,Service就是一个Client,ServiceManager就是一个Service。他们之间也是通过Binder来通信
简单来说,ServiceManager中维护了一张表,表的键String类型的键,值为Binder对象引用。Client通过名字就可以获取到Binder实体的应用。
ServiceManger的主要工作是提供了addService/getServcie接口,提供Service的注册、获取。
过程:
Server创建了Binder实体,为其取一个字符形式,可读易记的名字,将这个Binder连同名字以数据包的形式通过Binder驱动发送给SMgr,通知SMgr注册一个名叫张三的Binder,它位于某个Server中。驱动为这个穿过进程边界的Binder创建位于内核中的实体节点以及SMgr对实体的引用,将名字及新建的引用打包传递给SMgr。SMgr收数据包后,从中取出名字和引用填入一张查找表中
- 服务端 提供具体服务的Service。 一般通过AIDL创建
- 客户端 服务使用方。
Service,client,ServiceManager 运行与用户控件。
Binder驱动运行与内核控件。
四个角色之间的关系:(图片来自Android进程间通信(IPC)机制Binder简要介绍和学习计划)

Framwork层和native层的对应关系
binder的四个角色,基础是native层的支持,framwork层也有同样的一层,与native层相对应。
图片来自Binder系列7—framework层分析。作者写的这一个Binder系列,新手可以从系列10开始看,先有个整体的把我,在去看各个细分章节。

Binder中的线程
Client线程:
Client运行在当前的调用线程。当调用Binder接口后,会使当前线程进入休眠状态,知道服务端处理完接口调用,并返回数据。若使用CallBack或者不需要调用返回数据,则调用后结束。服务端
服务端收到Binder接口调用请求后,Binder驱动会根据Service中的线程池状态,分配线程池的一个worker线程执行,执行完后唤醒Client请求线程。若此时线程池满,则会进入TODO队列,等待线程空闲。
所以当Client请求操作未耗时操作时,不要在主线程中进行,否则容易引起ANR。
这个图片可以说明Cliet、Service间的线程关系。其实这个图是用来说明通信协议的。图片来自:Binder系列2—Binder Driver再探

Binder线程池默认最大拥有16个线程,主线程是和进程创建一起创建的。其他线程Binder驱动根据当前Cliet请求情况创建。主线程是不会退出的,为Binder进程的守护线程。
问:Binder进程最多可以服务多少个请求?

问:Binder线程都被阻塞后会出现上面情况?

Binder通信过程中的内存拷贝
Binder 只经过一次内存拷贝。Client从用户空间拷贝数据到内核空间,由于内核空间与Service的用户控件是共享内存的。Service通过偏移内存地址的方式获取共享的数据。
如下图:

binder数据数据相关
Binder可以传递任意大小的数据吗?答案是否定的?

想传递更多数据怎么办?

通过BInder可以实现跨包共享私有文件吗?

Binder进程最多可以服务多少个请求?

Binder使用
- AIDL
- 当然你可以装逼下,自己手写AIDL调用。
- Messager(底层还是AIDL)
- ContentResolver(底层还是AIDL)
同进程Binder 与不同进程Binder有和异同。
注意,当AIDL中的Client、Service在同一个进程中时,则service、Client中的IBinder为同一个对象。怀疑是不是ServiceManger中的mCache直接返回的。当不在同一个进程时,不是同一个对象?为什么,哪位知道告诉我下。
Binder死亡通知

参考:
-
本篇文章是提纲挈领的文章,可以细看,了解binder的的全貌。
http://gityuan.com/tags/#binder。
gityuan作者写的非常好,但个人觉得太深入代码细节。初学者会被绕来绕去的代码分析弄晕掉,前期建议不要看的太细,大略过一遍就好。