Binder

2019-04-12  本文已影响0人  程序设计法师

Binder是基于OpenBinder来实现的,由client、server、Service Manager(服务管理)和Binder驱动程序等系统组件组成,binder驱动运行在内核空间,其他则运行在用户空间
client和server就是在serviceManager和binder驱动提供的基础设施上实现通信的

binder.png

binder驱动程序提供设备文件“/dev/binder”与用户空间交互,client,server和serviceManager通过文件操作函数open()和ioctl()与binder驱动程序进行通信

serviceManager是一个保护进程,他负责告知binder驱动程序他是binder机制的上下文管理者,用来管理server,并向client提供查询server接口的功能,所以serverManager必然要和server以及client进行通信,serverManager、client、server、分别是运行在独立的进程中,他们之间的通信也属于进程间通讯,而且也是采用binder机制进行通信

serverManager.png

简要总结下ServiceManager成为Android进程间通信机制Binder保护进程的过程

1 打开 “/dev/binder”文件
open(“/dev/binder”,O_RDWR);
2 建立128kb内存映射
mmap(null,mapsize,PROT_READ,MAP_PRIVATE,bs->fd,0);
3 通知Binder驱动程序他是保护进程
binder_become_context_manager(bs);
4 进入循环等待请求的到来
binder_loop(bs,svcmgr_handler);

serverManager在binder机制中既充当保护进程的角色也充当着server角色,但是他与一般的server不一样,对于普通的server来说,client如果想要获得server的远程接口,必须通过serviceManager远程提供的getService接口来获得,这本身就是一个使用binder机制来进行进程间通信的过程,却不必通过进程间通讯机制来获得,因为serviceManager远程接口是一个特殊的Binder引用,他的引用句柄一定是0

创建的Service Manager远程接口本质上是一个BpServiceManager,包含了一个句柄值为0的Binder引用

匿名共享子系统详解

Android系统提供了独特的匿名共享内存子系统Ashmem,他以驱动程序的形式在内核空间中实现,Ashmem有如下两个特点:

1 能够辅助内存管理系统来有效的管理不再使用的内存块
2 通过binder进程间通信机制来实现进程间的内存共享

在系统运行时库层和应用程序框架层提供了访问接口,其中在系统运行时库层提供了C/C++调用接口,而在应用程序框架层提供了Java调用接口,在此我们将直接通过应用程序框架层提供的Java调用接口来说明 Ashmem子系统的使用方法,对于应用程序框架层的java调用接口来说,是通过JNI方法调用系统运行时库层的C/C++调用接口,最后需要进入到内核空间的Ashmem驱动程序中去

Ashmem驱动程序,利用Linux的共享内存子系统导出的接口来实现自己的功能,在Android系统Ashmem系统中,其核心功能是实现创建(open)、映射(mmap)、读写(read/write)以及锁定和解锁(pin/unpin)

Ashmem驱动程序并不提供文件的read操作和write操作,如果进程要访问这个共享内存,则必须将这个设备文件映射到自己的进程空间中,然后才能进行内存访问,在类MemoryFile的构造函数中,创建Ashmem后需要把Ashmem设备文件映射到进程空间,映射功能是通过调用JNI方法native_mmap实现的

如果想在Android进程之间共享一个完整的Ashmem块,可以通过调用接口MemoryHeapBase来实现,如果只是想在进程之间共享Ashmem块中的一部分时,可以通过调用接口MemoryBase来实现

接口MemoryBase以接口MemoryHeapBase为基础,这两个接口都可以作为一个Binder对象在进程之间进行传输,因为接口MemoryHeapBase是一个Binder对象,所以拥有Server端对象(必须实现一个BnInterface接口)和client端引用(必须要实现一个BpInterface接口)

Java访问接口层详解

在Android应用程序框架层,通过使用接口MemoryFile来封装匿名共享内存文件的创建和使用
构造方法MemoryFile以指定的字符串调用了JNI方法native_open,目的是建立一个Ashmem文件,这样可以得到一个文件描述符,然后使用这个文件描述符为参数调用JNI方法native_mmap,并把Ashmem文件映射到进程空间中,这样就可以通过映射得到地址空间的方式直接访问内存数据

在类MemoryFile的成员函数readBytes,功能是读取某一块Ashmem内容,成员函数writeBytes功能是写入某一块Ashmem内容,isDeactivated功能是保证Ashmem已经被映射到进程的地址空间中

上一篇下一篇

猜你喜欢

热点阅读