Binder是Android的一种特色的跨进程的通信方式
和AIDL的关系
AIDL是封装了Binder的一种框架,使使用Binder,进行跨进程更加方便。
为什么要学习Binder
例如startActivity,网络硬件各种服务,都使用到了跨进程的通讯,在系统层,Binder无处不在。
Binder的例子
Binder相当于网络通讯中的路由器,只不过Binder是一个虚拟的设备

Binder的由来
Linux内核以具备很多跨进程通讯方案
1.管道,耗费性能
2.共享内存,使多个进程可以访问同一块内存空间,管理混乱
3.Socket适合于网络通讯,但对于进程间通讯,显然不适合
…
那为什么还要用Binder?
- 考虑安全性,本身就支持对通讯的双方进行身份的校验
- 性能,效率比较高
Binder四个重要角色
- Server
- Client
- ServiceManager
- Binder驱动 (默认最大数是16,超过会阻塞,等待)

Binder四个重要角色
- IBinder:接口,代表了跨进程通讯的能力
- IInterface:代表Server端具备什么样的功能,什么样的能力,能提供哪些方法,对应的就是AIDL定义的接口
- Binder:继承自IBinder,是java实现类,在跨进程的时候,BInder驱动会自动进行Binder和BInderProxy的转换。
- Stub:AIDL会自动生成一个Stub类,继承自Binder,实现IInterface接口,是一个抽象类,具体的IInterface相关实现,需要开发者自己实现
Binder的优点

Binder驱动

Binder原理图

Binder通信机制完整流程

Binder流程
- 打开Binder设备
- buffer创建 (用于进程间数据传递)
- 开辟内存映射 (128K)
- ServiceManager启动
- 打包Parcel中,数据写入Binder设备,copy_from_user
- 服务注册,添加到链表svclist中
- 定义主线程中的线程池
- 循环从mIn和mOut中取出读写请求,发到Binder设备中
来看下源码
frameworks/native/cmds/servicemanager.c
打开binder设备文件,返回文件描述符

然后在/frameworks/native/cmds/servicemanager/binder.c

打开binder设备驱动的时候,通过mmap开启内存的映射128K
那什么时候调用了mmap呢 ? (开辟内存映射)
在device google cuttlefish_kernel 4.4-x86_64/System.map中
Android9.0在25306行,可以找到binder_mmap

即,System.map启动的时候,开启了binder的mmap,开辟了内存映射
然后来看ServiceManager的启动
在/system/core/rootdir/init.rc

然后来看打包Parcel中
在frameworks native libs binder IServiceManager.cpp

会将service的信息打包到Parcel中,然后通过remote->transact往下一步进行传输
然后数据怎么写入Binder设备?
来看/frameworks /ative/libs/binder/IPCThreadState.cpp

writeTransactionData:将Parcel中的信息封装成结构体写入
waitForResponse:将设备写入到Binder当中,并且等待返回的结果
服务是如何注册的?
在frameworks/native/cmds/servicemanager.c
svc_can_register:做了权限的检查,是否有注册service的权限
find_svc:在svclist这个链表里去查找,看是否已被注册过
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));:没有注册过,那么就分配一个服务管理的结构svcinfo,并将其添加到svclist中
si->next = svclist;:将代表该服务的结构插入到链表中来
binder_acquire(bs, handle);:增加Binder的应用技术
binder_link_to_death(bs, handle, &si->death);:如果该服务退出之后,那么就要通知ServiceManager

定义主线程中的线程池
frameworks/native/libs/binder/IPCThreadState.cpp
定义主线程中的线程池,来进行不停地写不停地读的过程

循环从mIn和mOut中取出读写请求,发到Binder设备中
pthread_setspecific:将对象设为当前线程的私有
mIn.setDataCapacity(256);mOut.setDataCapacity(256);: 输入输出各分配256字节,不断从mIn,mOut中来进行一些读写,然后发送到binder中来


本文深入探讨了Android中Binder机制的工作原理,包括其作为跨进程通信方式的重要性,与AIDL的关系,Binder的角色划分,以及Binder驱动的详细流程。通过具体示例和源码分析,帮助读者理解Binder如何在系统层实现高效、安全的通信。
32

被折叠的 条评论
为什么被折叠?



