美文网首页
Android binder机制

Android binder机制

作者: 三十五岁养老 | 来源:发表于2022-03-11 18:37 被阅读0次

IPC常见方式

image.png
  1. Bundle
  • 优点: 简单易用
  • 缺点: 只能传输Bundle支持的数据类型
  • 使用场景: 四大组件间的进程间通信
  1. 文件共享
  • 优点 简单易用
  • 缺点 不适合高并发场景,无法做到即时通信
  • 使用场景: 无并发访问请教,简单交换的数据实时性不高的场景
  1. AIDL
  • 优点:功能强大,支持一对多并发通信,支持实时通信
  • 缺点: 使用复杂些
  • 使用场景: 一对多,RPC需求
  1. ContentProvider
  • 优点: 在数据源访问方面功能强大,支持一对多并发数据共享,可通过Call方法扩展其他操作
  • 缺点 受约束的AIDL,主要提供数据源的CRUD操作
  • 使用场景: 一对多的进程间数据共享
  1. Socket
  • 优点功能强大,可以通过网络传输字节流,支持一对多并发实时通信
  • 缺点 实现细节稍微有点麻烦,不支持直接RPC
  • 使用场景: 数据交换

Binder是什么?

Binder是Android提供的一套进程间相互通信框架
系统服务ActivityManagerService,LocationManagerService,等都是在单独进程中的,使用binder和应用进行通信。

Android系统框架

image.png

Android系统分成三层。最上层是application应用层,第二层是Framework层,第三层是native层。
由下图可知几点:

  1. Android中的应用层和系统服务层不在同一个进程,系统服务在单独的进程中。

  2. Android中不同应用属于不同的进程中。

Android应用和系统services运行在不同进程中是为了安全,稳定,以及内存管理的原因,但是应用和系统服务需要通信和分享数据。

优点

  • 安全性:每个进程都单独运行的,可以保证应用层对系统层的隔离。
  • 稳定性:如果某个进程崩溃了不会导致其他进程崩溃。
  • 内存分配:如果某个进程以及不需要了可以从内存中移除,并且回收相应的内存。

Binder通信

image.png

一个进程是不能直接直接操作另一个进程的,比如说读取另一个进程的数据,或者往另一个进程的内存空间写数据,进程之间的通信要通过内核进程才可以
client和service并不想知道binder相关协议,所以进一步client通过添加proxy代理,service通过添加stub来进一步处理与binder的交互。

Activity请求Activity ManagerService服务为例:

  • ActivityManagerService通过调用serviceManager中的addService方法,然后调用ServiceManagerNative类中的addservice(name)方法。

  • ServiceManagerNative会通过Binder发送一条SVG_MGR_ADD_SERVICE的指令,然后通过svcmgr_handler()调用do_add_service()方法往svc_list中添加相应的service。

  • client要请求服务,比如说在activity中调用context.getSystemService()方法,这个时候serviceManager就会使用getService(name),然后就会调用到native层中的ServiceManagerNative类中的getService(name)方法。

  • ServiceManagerNative会通过Binder发送一条SVG_MGR_GET_SERVICE的指令,然后通过svcmgr_handler()调用do_find_service()方法去svc_list中查找到相关的service。

  • 查找到相应的服务后就会通过Binder将服务传给ServiceManagerNative,然后传给serviceManager,最后client就可以使用了。

服务是在svclist中保存的,svclist是一个链表,因此客户端调用的服务必须要先注册到svclist中。

Binder结构设计

image.png
  • Java层AIDL
  • Framework层, Android.os.Binder
  • Native 层: libBinder.cpp
  • 内核层的通信都是通过ioctl来进行的,client打开一个ioctl,进入到轮询队列,一直阻塞直到时间到或者有消息。

Binder中使用的设计模式

1、代理模式(Proxy Pattern )
在Android中client不是直接去和binder打交道,client直接和Manager交互,而manager和managerProxy交互,也就是说client是通过managerProxy去和binder进行交互的。同时service也不是直接和binder交互,而是通过stub去和binder交互。

Binder与内存映射mmap

Binder IPC 是基于内存映射(mmap)来实现的,但是 mmap() 通常是用在有物理介质的文件系统上的。
进程中的用户区域是不能直接和物理设备打交道的,如果想要把磁盘上的数据读取到进程的用户区域,需要两次拷贝(磁盘–>内核空间–>用户空间);通常在这种场景下 mmap() 就能发挥作用,通过在物理介质和用户空间之间建立映射,减少数据的拷贝次数,用内存读写取代I/O读写,提高文件读取效率。

而 Binder 并不存在物理介质,因此 Binder 驱动使用 mmap() 并不是为了在物理介质和用户空间之间建立映射,而是用来在内核空间创建数据接收的缓存空间。

一次完整的 Binder IPC 通信过程通常是这样:

  • 首先 Binder 驱动在内核空间创建一个数据接收缓存区;
  • 接着在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系;
  • 发送方进程通过系统调用 copyfromuser() 将数据 copy 到内核中的内核缓存区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。

Binder传输数据的大小限制

Activity之间传输BitMap的时候,如果Bitmap过大,就会引起问题,比如崩溃等,这其实就跟Binder传输数据大小的限制有关系,在上面的一次拷贝中分析过,mmap函数会为Binder数据传递映射一块连续的虚拟地址,这块虚拟内存空间其实是有大小限制的

普通的由Zygote孵化而来的用户进程,所映射的Binder内存大小是不到1M的,准确说是 110241024) - (4096 *2) :这个限制定义在ProcessState类中,如果传输说句超过这个大小,系统就会报错,因为Binder本身就是为了进程间频繁而灵活的通信所设计的,并不是为了拷贝大数据而使用的:

系统服务与bindService等启动的服务的区别

image.png

服务可分为系统服务与普通服务
服务的启动方式 :

  • 系统服务一般是在系统启动的时候,由SystemServer进程创建并注册到ServiceManager中的,这些服务本身其实实现了Binder接口,作为Binder实体注册到ServiceManager中,被ServiceManager管理,而SystemServer进程里面会启动一些Binder线程,主要用于监听Client的请求,并分发给响应的服务实体类,可以看出,这些系统服务是位于SystemServer进程中

  • bindService类型的服务,这类服务一般是通过Activity的startService或者其他context的startService启动的,这里的Service组件只是个封装,主要的是里面Binder服务实体类,这个启动过程不是ServcieManager管理的,而是通过ActivityManagerService进行管理的

服务的注册与管理:

  • 系统服务一般都是通过ServiceManager的addService进行注册的,这些服务一般都是需要拥有特定的权限才能注册到ServiceManager
  • bindService启动的服务可以算是注册到ActivityManagerService,只不过ActivityManagerService管理服务的方式同ServiceManager不一样,而是采用了Activity的管理模型,详细的可以自行分析

使用方式:

  • 使用系统服务一般都是通过ServiceManager的getService得到服务的句柄,这个过程其实就是去ServiceManager中查询注册系统服务。
  • 而bindService启动的服务,主要是去ActivityManagerService中去查找相应的Service组件,最终会将Service内部Binder的句柄传给Client。

Binder请求的同步与异步?

  • 在单次Binder数据传递的过程中,其实都是同步的。只不过,Client在请求Server端服务的过程中,是需要返回结果的,即使是你看不到返回数据,其实还是会有个成功与失败的处理结果返回给Client,这就是所说的Client端是同步的。
  • 服务端是异步的,可以这么理解:在服务端在被唤醒后,就去处理请求,处理结束后,服务端就将结果返回给正在等待的Client线程,将结果写入到Client的内核空间后,服务端就会直接返回了,不会再等待Client端的确认,这就是所说的服务端是异步的,

Android APP有多少Binder线程,是固定的么?

Android APP上层应用的进程一般是开启一个Binder线程,而对于SystemServer或者media服务等使用频率高,服务复杂的进程,一般都是开启两个或者更多。驱动会根据目标进程中是否存在足够多的Binder线程来告诉进程是不是要新建Binder线程。

Binder如何精确制导,找到目标Binder实体,并唤醒进程或者线程?

  • 首先Service会通过addService将binder实体注册到ServiceManager中去,Client如果想要使用Servcie,就需要通过getService向ServiceManager请求该服务。
  • 在Service通过addService向ServiceManager注册的时候,ServiceManager会将服务相关的信息存储到自己进程的Service列表中去,同时在ServiceManager进程的binder_ref红黑树中为Service添加binder_ref节点,这样ServiceManager就能获取Service的Binder实体信息。
  • 当Client通过getService向ServiceManager请求该Service服务的时候,ServiceManager会在注册的Service列表中查找该服务,如果找到就将该服务返回给Client,在这个过程中,ServiceManager会在Client进程的binder_ref红黑树中添加binder_ref节点,可见本进程中的binder_ref红黑树节点都不是本进程自己创建的,要么是Service进程将binder_ref插入到ServiceManager中去,要么是ServiceManager进程将binder_ref插入到Client中去。
  • Client就能通过Handle句柄获取binder_ref,进而获取到binder_proc与binder_node信息,之后Client便可有目的的将binder_transaction事务插入到binder_proc的待处理列表,进而访问Service服务。
  • ServiceManager是比较特殊的服务,所有应用都能直接使用,因为ServiceManager对于Client端来说Handle句柄是固定的,都是0,所以ServiceManager服务并不需要查询,可以直接使用。

参考链接:
https://blog.csdn.net/happylishang/article/details/62234127
https://www.jianshu.com/p/adaa1a39a274

相关文章

  • Android流程原理图

    android应用启动流程 android系统启动过程 binder架构 binder机制 onCreate() ...

  • 2018-09-04 binder

    【转】图文详解 Android Binder跨进程通信的原理 [【转】](Android Binder机制(超级详...

  • Binder 总结

    什么是binder binder是Android 中的一种进程间通信机制(IPC机制) binder 为什么会出现...

  • 移动架构07-Binder核心机制

    移动架构07-Binder核心机制 一、什么是Binder 从机制上说,Binder是一种Android中实现跨进...

  • Binder

    Binder是Android中跨进程通信的一种机制,Binder机制的优点有: 1.高效 Binder数据拷贝只需...

  • Android Review - Binder机制(二)

    前一篇我们从理论上来了解Android的Binder机制,本篇从实战来深入了解Android的Binder机制。 ...

  • Android源码分析之认识Binder

    1.什么是Binder机制 Binder机制是Android系统中进程间通讯的一种方式,是Android系统实现I...

  • Android开发者需掌握的进阶技能

    1:熟悉各大Android 机制(handler机制,事件分发机制,binder机制...) 2:熟悉 view ...

  • 对Binder的实现原理的理解

    写给 Android 应用工程师的 Binder 原理剖析简单理解Binder机制的原理 aidl Android...

  • 12 Binder原理-Native 层-ServiceMana

    根据Android系统的分层,Binder机制主要分为以下几个部分: Binder机制涉及到的类image.png...

网友评论

      本文标题:Android binder机制

      本文链接:https://www.haomeiwen.com/subject/wkmcdrtx.html