3. Android binder设计篇

  • 时间:
  • 浏览:0

通知用户空间线程池,binder driver处置成功

binder driver上边的binder引用对象。

太多,binder 机制才通过这种 通过命令调用的最好的法律妙招,通知service线程池为指定的binder本地对象增加/减少引用,从而达到维护用户空间service线程池binder本地对象生命周期的目的。

二. Android Binder简介

10. service线程池被service manager线程池唤醒日后,会回到service线程池的用户空间,后要把第8步binder driver拷贝service线程池内存的数据读取出来(这块内指在binder driver中,被service线程池和binder driver并肩映射),再完成最后的逻辑。

在用户空间线程池请求BC_CLEAR_DEATH_NOTIFICATION命令后,binder driver返回这种 命令通知用户空间线程池

Binder作为Android上边线程池间通信机制,主要有有五个模块参与这种 过程,分别是

这是我们儿要求使用binder时都可以传输大于1MB数据的原困,比如通过intent传输图片,很有后要要超过binder传输上限。当然这种 我们儿在上边分析代码的之也有看了。

这是后要binder driver是在内核空间,binder本地对象在service线程池的用户空间,都可以直接引用。

19. 在client线程池用户空间,把句柄值拷贝出来,封装成有五个BpBinder对象,BpBinder对象上边mHandle值就保存了这种 句柄值。

1. BC_XXX

通过上边几点介绍,一到七点保证了binder间线程池通信,第八点保证了生命周期管理,一切看起来都没法完美。

后要都可以 说明的是这1五个线程池指的是binder driver请求用户空间线程池创建的最大线程池数(当应用线程池线程池数不够以响应binder请求时,binder driver会请求应用线程池分配线程池),暂且包括用户空间线程池主动注册到binder driver的。

client线程池引用service线程池的有五个binder本地对象正在通信,后要这种 日后service线程池把这种 binder本地对象回收了为甚么办?

11. client线程池启动后,也会像service和service manager一样通过open和mmap最好的法律妙招请求binder driver为client线程池分配一块内存用户线程池间通信。

通知binder driver减少目标service弱引用,参数int表示目标service的handle值.

2. BR_XXX

9. service manager在binder driver完成日后,会再次线程池守候情況。

binder_ref主要的作用太多我拥有有五个句柄值,并肩指向有五个binder_node binder实体对象。

5. binder driver接到service的ioctl调用后,找到第2点描述的sm binder实体,后要通过这种 sm binder实体找到service manager对应的线程池。

这种 难题就回到文章现在开始 的第有些,上边在描述女娲造人关于源头这种 难题上的日后,我们儿说神话故事上边假设女娲是日后指在的,从而弥补了这种 故事上边的漏洞。

那,binder driver为这种 不直接引用binder 本地对象呢?

通知binder driver增加目标service 强引用,参数int表示目标service的handle值.

通知用户空间线程池,binder driver处置跳出异常

7. service manager线程池被唤醒后,回到service manager用户空间,并肩把binder driver拷贝过来的数据读取出来,把名称和从binder driver传入的句柄值保存起来,再次执行结果通过ioctl指令通知binder driver。

为了更好的说明,先上一张整体Binder的关系图。

在上边我们儿说起过,有五个线程池中后要有多个service组件,比如service2线程池,那在binder driver上边也是这种 关系。

后要有俩我人及 想进入火车候车室,没法他都可以 火车票后要站台票,另有五个们现在来做如下移觉:

太多还都可以区分。

通知用户空间线程池所监听的binder本地对象后要销毁

BC_REGISTER_LOOPER是binder driver发现此用户空间线程池的线程池无法响应binder通信,都可以 创建新线程池;后要向目标用户空间线程池发出请求创建线程池命令

android_proj/framework/base/libs/binder/ProcessState.cpp

client

三.Binder通信关系总图

比如addService的日后,binder driver请求service manager去注册有五个service。

为了处置这种 难题,binder机制使用了引用的概念:

binder driver把这块内存划成一页一页来管理,那有五个binder_buffer就表示一页。

b. binder driver记录下了这层对应关系。

后要binder driver在请求service线程池增加有五个service组件的强引用日后,它都可以 守候service组件增加强引用计数的结果,它都可以 根据这种 结果修改我人及 的有些情況。

   size_t maxThreads = 15;  

android_proj/framework/base/libs/binder/ProcessState.cpp

   result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);

此时,service manager的线程池正在睡眠守候情況,于是binder driver把要处置的工作封装成有五个binder_transaction丢给service manager线程池,也太多我把数据拷贝到binder driver为service manager分配的那块内存(也太多我第2步binder driver为service manager分配的那块内存),这也是binder数据传输的唯一一次数据拷贝,后要唤醒它。

2. service manager首先注册为binder driver的服务管理者,注册的过程中,service manager会调用open和mmap最好的法律妙招来通知binder driver为它分配一块最大不超过4MB的内存,当然这种 大小还都可以由service manager来指定,service manager指定的是128KB。这块内存并肩被有五个虚拟地址应用,有五个binder driver的有五个是service manager的。

5. 在上图中我们儿看了有些service线程池中后要指在多个service组件,比如service2线程池。它们都通过binder driver注册到了service manager,后要它们有不同的名称对应以及不同的service组件地址,这有五个区别分别会被service manager和binder driver(通过binder_node底部形态体的cookie数据)所记住。

同第2点一样,这块内存也被binder driver内核空间和service线程池用户空间的虚拟地址并肩映射。

1. 后要把进入候车室这种 功能移觉成实现binder通信这种 功能,没法:

12. client线程池向service manager发起查询service请求,并肩传入要查询service的名称,传入的binder句柄值是0,也太多我对应着service manager。

那后要binder本地对象意外的挂了呢?比如service所在线程池后要线程池逻辑错误异常退出了,调用它的client为甚么办呢?

  ...

client和service作为通信的模块很容易理解,后要client都可以 和service通信,太多它们有五个必然会成为通信的一次责。

client请求binder driver注册目标service组件的死亡通知

提供服务的service线程池死亡了为甚么办?

3. 后要我们儿看了看了对于service manager在binder driver中, client和并没法binder引用对象,而有些service在client线程池中却有binder 引用对象,这是为这种 呢?

后就说 第1种情況,线程池会我人及 主动close掉我人及 线程池打开的binder driver;从而调用到binder driver的binder_release函数。

最后把这种 属于我人及 线程池的Binder引用对象和我人及 线程池内的有五个Binder代理对象对应起来;另有五个client就间接的拥有了service Binder本地对象的引用,进而还都可以和service通信。

句柄值对应client上边的binder代理对象BpBinder上边的mHandle,太多client还都可以根据mHandle找到内核对应的binder_ref数据。

所谓的实名和匿名是针对service manager而言的,太多我service manager知谁能谁能告诉我这种 binder对象的指在,后要给它有五个名字相对应。

通知binder driver增加目标service 弱引用, 参数int表示目标service的handle值,

那有些同学就会问了,这里说Binder设计,为这种 要提到女娲造人的故事呢?这是后要二者在源头这种 难题的处置上有异曲同工之妙,嗯,上边会再做说明。

另有五个们还都可以来做另有五个两种假设:

在天地混沌之际,上神女娲后要实在我人及 太孤单,没法跟它并肩嗨,决定按照我人及 的模样加上有些生物;于是呢,捏泥为人,并赋予了人生育的能力,太多女娲被称为了人类的母亲;

6. 此时,service线程池会返回service线程池用户空间,然也有再次进入binder driver,后要进入守候情況;它都可以 守候service manager注册service的返回结果。

Binder Driver

没法client和service后要传入句柄0就还都可以找到service manager在binder driver中的binder实体对象,自然太多我都可以 binder 引用对象了。

后要service manager线程池太多我会像有些service线程池一样,后要指在多个service服务。

另有五个,整个通信过程就基本现在开始 了。

八. 引用计数

open_driver(){

13. binder driver接受到client的查询请求后,根据句柄值0找到service manager的binder实体对象(sm binder实体),后要通过sm binder实体对象找到service manager线程池。此时,service manager线程池正指在守候情況。

}

ioctl指令BINDER_WRITE_READ的数据底部形态。

五. 实名binder对象和匿名binder对象

那binder_transaction_data就刚好是用来描述从用户空间到内核空间传输binder_transaction数据的。

14. binder driver把从client传入的数据拷贝到为service manager分配的那块内存,生成有五个binder_transaction,后要唤醒service manager线程池。

在linux系统中对于权限安全性管理,UID是有五个不得劲要的东西,太多对于安全性,binder就在binder driver上边负责填写调用线程池的UID和PID;相比有些在应用线程池填写UID和PID的线程池间通信机制,安全性得到了极大提高。

没法这种 操作

4. BR_XXX

15. client线程池经过有些处置后进入守候情況,守候service manager来唤醒。

具体还都可以参考./working_directory/kernel/goldfish/driver/staging/android/binder.h

Andoid Binder从Open Binder发展而来,提供了跨线程池通信机制;实在linux后要提供太多的跨线程池机制,比如管道,共享内存等等,那为这种 google要使用binder呢?

BC_ENTER_LOOPER是用户空间线程池主动通知binder driver的,

4. 购买站台票也有想买就还都可以买的,都可以 持有火车票吃还都可以购买站台票;

3. 后要火车票是实名制的,太多铁道部能知道卖出的票和购买人的***一一对应;后要对于站台票,铁道部暂且能知道这种 对应关系;

16. service manager被唤醒后,把binder driver拷贝给它的数据读取出来,当然最重要的是从client线程池传入的service 名称。通过查找,找到名称对应的句柄值。也太多我第7点那个名称和句柄值。后要通过ioctl再次回到binder driver。

ps:

binder_proc和binder_node是一对多的关系。

client线程池引用service线程池的有五个binder本地对象正在通信,后要service线程池的binder本地对象不指在了为甚么办?

3. BC_XXX

binder service对象描述,每个加上到binder driver的service也有对应有五个binder_node,包括service manager也是

4. service线程池启动后,同样会通过open和mmap最好的法律妙招通知binder driver为service线程池分配一块不超过4MB的内存,一般应用线程池的是1MB左右(1mb - 8kb)。

2. 异常退出,比如后要线程池上边的有五个逻辑错误原困线程池退出

6. binder线程池,用户空间的线程池有个线程池来响应binder driver,后要有个上限,一般是1五个线程池,详见

七. binder命令

3. 另有五个,binder driver就记录下了与service manager 对应的binder实体对象(也太多我图中的sm binder实体)。

详见:

binder_proc使用了红黑树的数据底部形态来描述了它上边binder_node。

后就说 第2种情況,操作系统会我能们close,从而也还都可以调用binder driver的binder_release函数。

后要service manager线程池进入守候情況,守候别的线程池来唤醒。比如别的线程池要注册service后要查询service。

1. 正常死亡,比如线程池我人及 退出

binder 机制死亡通知的过程是另有五个的:

binder driver请求用户空间线程池减少指定binder本地对象的弱引用

binder driver请求用户空间线程池增加指定binder本地对象的弱引用

九. 死亡通知机制

5. 对于检票口,不管是火车票还是站台票也有从检票口通过,太多检票口还都可以记录有些信息;同样,对于binder driver,不管是实名binder还是匿名binder也有通过binder driver,binder driver也会记录它们的信息。

从用户空间流向binder driver的命令被称为BC_XXX,也太多我binder command的简称;相应的从binder driver流向用户空间线程池的称为BR_XXX,也太多我binder return的简称。如下图:

17. binder driver通过binder_transaction找到第15点的client线程池和线程池,通过从service manager返回的句柄值找到binder driver上边对应的service 实体对象。后要唤醒client线程池。

太多Binder driver提供了有五个桥梁,并肩在通信的过程中记录了有些数据。

对于所有的binder 命令,还都可以用下面两张表来描述:

1. 这里说的service和android应用上边说的4大组件service并也有有五个概念,这里的service指的是提供Binder服务的Binder本地对象。

binder driver反馈目标binder对象后要死亡,返回错误。

通知binder driver BR_INCREFS命令执行完毕,一般由service线程池在处置完binder driver的BR_INCREFS命令后向binder driver发出。

binder driver请求用户空间线程池分配有五个线程池;这种 情況一般是在用户空间线程池线程池无法处置binder driver间通信请求的情況下。

过程简短描述:

后要向service manager注册service;正如第2点所言,binder driver强制规定了0号句柄对应的是service manager实体对象,太多service线程池后要传入0号句柄,后要把想注册的service并肩传入过来就还都可以了。

跟binder本地对象死亡通知有关。

18. 在binder driver上边,client线程池根据service 实体对象,生成属于client线程池的binder引用对象,也太多我有五个句柄值,再返回client线程池用户空间。

在前面描述过,binder driver会为每个线程池分配有五个不超过4MB的内存,用来传输数据。

}

用户空间线程池创建线程池完毕后,会调用BC_REGISTER_LOOPER通知binder driver。

24. service完成我人及 的逻辑后,再次通过binder_ioctl通知binder driver,告诉binder driver处置结果,后要再唤醒client线程池。这种 过程就和service manager通知service是一样的了。

  ...

3. 安全性,手机涉及了少许的用户隐私,比如支付宝账号,电话本联系人号码,短信记录,通话记录等等;

我们儿知道binder机制是另有五个的引用的。

此命令是binder driver通知用户空间线程池创建线程池后,用户空间线程池创建线程池也有调用此命令,通知binder driver此线程池后要准备好。

21. binder driver根据mHandle句柄值找到client线程池内对应的binder引用对象,再根据binder引用对象找到它对应的binder实体对象,再根据binder实体对象找到其所在的binder线程池。后要把数据拷贝到binder driver为service线程池分配的那块内存,再唤醒service线程池。

那对于service manager和实名binder,匿名binder也是这种 关系 -- service mangager清楚的知道所有实名binder的名称,binder服务所在的线程池等等信息,后要对于匿名binder却一无所知,它甚至谁能谁能告诉我匿名binder的指在。

2. 火车票和站台票都还都可以进入候车室,也太多我说实名binder和匿名binder都还都可以完成线程池间通信功能,这点并没法这种 区别。

c. Binder实体对象,运行在Binder driver内核空间,对应的数据是binder_node底部形态体。

六. binder ioctl指令

正如第一步上边所描述的女娲造人的故事,女娲还都可以造人,后要人也还都可以造人。后要把女娲移觉成service manager,没法第一代人太多我实名binder对象,第一代人以及上边的人造的人太多我匿名binder对象;

binder_transaction用来描述binder driver上边的有五个事务。事务在数据库上边用的比较多,binder driver也借用了这种 概念。

     本文转自rongwei84n 51CTO博客,原文链接:http://blog.51cto.com/483181/1744571,如需转载请自行联系原作者

太多,通过这种 层层的关联,都连接起来了。

BpBinder(mHandle)->binder_ref->binder_node->BBinder binder本地对象。

d. 后要根据binder实体对象找到所有引用它的binder引用对象,后要发现binder引用对象有注册死亡通知,没法就封装有五个binder_work项给binder引用对象所在的线程池,后要唤醒它;让那个线程池去完成我人及 的逻辑。

后要强制规定sm binder实体对象对应的是句柄值是0。也太多我有些线程池来访问service,后要它传到binder driver的句柄值是0,那就说 原困目标service太多我service manager。

在初步了解binder机制的通信过程后,我们儿都可以 更深一步的了解binder通信,太多都可以 简单讲解下binder通信过程中的数据底部形态。

enum BinderDriverCommandProtocol {

a. Binder代理对象,运行在client用户空间,对应的类是BpBinder,实现的关键在于它有个句柄mHandle变量,通过这种 变量还都可以在Binder driver内核空间上边找到对应的Binder引用对象。

实在,我们儿也还都可以思考下,针对于移动设备这种 低配置的设备(相对于服务器),新的线程池间通信机制都可以 具备这种 新的优点呢?

那service manager和Binder driver起的作用是这种 呢?

2. 上边说的Binder代理对象,Binder引用对象,Binder实体对象,Binder本地对象是按照从client到service的顺序的,还都可以按个解释下这几只对象的含义。

#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))

太多为了次责处置这种 难题,binder后要死亡通知这种 功能,当binder本地对象消亡日后,都可以 通知正在监听它的binder_ref client。

d. Binder本地对象,运行在service用户空间,对应的数据是BBinder,实在太多我有五个提供服务的Binder service。

c. 当binder driver检测到目标service线程池后要死亡时,它找到这种 线程池所有binder本地对象在binder driver上边对应的binder实体对象。

暂不支持

binder driver请求用户空间线程池增加指定binder本地对象的强引用

client通知binder driver归还注册对某个service binder本地对象的死亡通知监听

client通知binder driver对某个service线程池的binder本地对象死亡通知处置完毕。

   ...

4. service manager请求binder driver为它分配的内存是128kb,一般应用线程池(client, service)请求binder driver为它分配的内存是1MB - 8KB。

对应有五个线程池,当线程池调用open最好的法律妙招打开binder driver的日后,binder driver会保存这种 线程池的相关信息,太多我用binder_proc这种 数据底部形态。

}

这张图后要基本包括了binder通信过程中的所有对象,我们儿还都可以用言语来简略的描述下这种 过程和各个对象的含义,至于更全版的我们儿上边再讲。

通知binder driver去释放有五个binder_buff的内存,参数int表示此binder_buff在用户空间线程池的虚拟映射地址。

总体来说,Binder肯定是有五个不错的线程池间通信机制,后要android经过太多年的发展,后要Binder也有足够优秀的话,以google的技术实力,早就被google替换了吧!

2. 高效性,比如对于手机这种 东西,我们儿肯定希望它反应比较慢,界面流畅;

后要它对于女娲这种 service manager而言,女娲并谁能谁能告诉我它们的指在和名字。

flat_binder_object顾名思义太多我压扁了的binder_object,为这种 要压扁呢?是为了传输的需求,太多把binder对象从用户空间传输到binder driver内核空间的日后,就都可以 用到这种 数据底部形态,比如addService的日后。

service

通知binder driver减少目标service强引用,参数int表示目标service的handle值.

就好比说人是女娲造的,那女娲又是哪里来的呢?

对应这种 难题,client和binder driver都爱莫有利于,后要它们也无法控制service线程池的生命周期。又回到了第八点阐述的那个难题:

在第七点的表中,我们儿提到了所有的Binder协议命令,其中包括类似BC_INCREFS,BC_ACQUIRE,BC_RELEASE,BC_DECREFS类似的命令,表中解释是维护binder对象的引用计数;那为这种 要进行另有五个的设计呢?

binder命令按照命令的流向性分为两大类:

那为甚么来管理这块内存呢?

20. client和service通信,client使用第19步获取到的mHandle句柄值,发送给binder driver。

神话故事很美好,解释了人类的来源,后要这种 逻辑中实在有个不够,太多我女娲从哪里来的?

   ...

太多,类似的,binder机制上边也采用这种 概念。

binder driver请求用户空间线程池减少指定binder本地对象的强引用

23. 后要binder实体对象有个cookie值指向用户空间service线程池的的service地址,太多service在被唤醒后,它还都可以找到是由哪个service组件来响应此次服务(service线程池内后要不止有五个service组件)。

那在binder机制上边,也有这种 难题:太多我client通过service manager拿到service的binder句柄值,没法service为甚么拿到service manager的句柄值呢?

ServiceManager

另有五个,client就还都可以向service manager通过指定的名字去查询日后注册的service,从而找到对应的Binder实体对象,再继而生成属于我人及 线程池的Binder 引用对象。

好吧,跟神话故事一样,我们儿也是假设service manager是日后指在的,后要规定它的句柄值太多我0。

对于service线程池死亡,一般还都可以分为两种情況:

binder_ref关联的binder_node对象,另有五个,找到binder_ref后,就还都可以进一步找到binder_node。

b. Binder引用对象,运行在Binder driver内核空间,对应的数据是binder_ref底部形态体。

这种 移觉后要难以理解的话,那再举个更加现实的栗子:

22. client线程池的调用线程池进入守候情況。

那对于实名binder和匿名binder也是没法,匿名binder也有想创建就能创建的,首先都可以 得到有五个实名binder,通过实名binder得到匿名binder,具体例子还都可以参考bindService得到有五个匿名binder的实现。

此命令和BC_REGISTER_LOOPER的区别太多我

那Binder driver是做这种 用的呢?

这也是binder驱动的精华,通过这种 虚拟内存双重映射,减少了binder driver和service manager之间的数据拷贝。

四. binder机制中的数据底部形态

至此,binder设计篇内容全版提供完毕,下面会写有些binder实现篇的东西,也太多我从代码的高度来分析这种 内容。

通知binder driver此线程池退出

1. 首先这张图有有五个空间,用户空间和内核空间;client, service,service manager运行在用户空间;而binder driver运行在内核空间。

红黑树的数据底部形态我们儿有不清楚还都可以百度下。

enum BinderDriverReturnProtocol {

一. 引言--女娲造人的故事

太多,上边两种后要都还都可以在binder driver的binder_release函数中去处置。

binder_node上边讲过,关联了binder_proc,以及service线程池上边的service组件,也太多我binder本地对象。

service manager提供service的注册,查询等服务,那说的再明白有些,太多我service Binder本地对象把我人及 和有五个名字加上到service manager注册;

通知binder driver此线程池进入BINDER_LOOPER_STATE_REGISTERED情況,再经过有些处置就会进入就绪情況,还都可以处置线程池的事务。

Binder driver提供的是桥梁的作用,比如从service注册是service manager,抑或从client到service mangager查询service,以及从client到service的通信,都都可以 通过Binder driver。

a. client线程池拿到指向service线程池binder本地对象的引用后,它还都可以向这种 service线程池binder本地对象请求注册有五个死亡通知(实在太多我BpBinder,后要它实现了死亡通知的接口)。

1. 内存节省,后要移动设备的低配置,太多都可以 新的通信机制尽后要的节省资源,binder在跨线程池数据拷贝时只进行一次;

换句话太多我说binder driver为service manager分配了一块并肩被内核空间和用户空间映射的内存。

后要,还是有意外情況指在,那太多我:

在Java上边,我们儿知道维护有五个对象的生命周期还都可以通过强引用,软引用,弱引用和虚引用来实现(具体的区别我们儿还都可以百度,上边有些区别和技巧还是很有用的,不得劲是软引用用来实现图片的缓存),后要有五个对象被从垃圾回收的根节点强引用所关联,没法它是我太多 被回收的。

8. service manager线程池回到binder driver日后,通过日后第5步产生的binder_transaction找到日后调用的binder driver的service线程池和线程池,把第7点从service manager返回的结果读出来,后要拷贝到binder driver为service分配的内存,再唤醒service线程池。