Binder详解

参考文章:https://blog.csdn.net/freekiteyu/article/details/70082302
参考文章:https://www.cnblogs.com/qingchen1984/p/5212755.html
一。Binder的由来:
在Linux内核的操作系统中,为了数据的保护,某些进程之间是互不干扰的,这个技术叫做进程隔离,操作系统中会给进程分配一个虚拟地址空间供其使用,这也就是所谓的进程独享操作系统,其实就是独享这个虚拟地址空间。操作系统中进程之间的数据是不共享的,要向让进程之间通信,就需要一种进程间的通信机制,在Android中这个机制就是Binder通信机制。
Binder是Android系统中进程间通讯(IPC)的一种方式,也是Android系统中最重要的特性之一。Android中的四大组件Activity,Service,Broadcast,ContentProvider,不同的App等都运行在不同的进程中,它是这些进程间通讯的桥梁。正如其名“粘合剂”一样,它把系统中各个组件粘合到了一起,是各个组件的桥梁。

image.png

实现Binder跨进程间的通信是通过Clent-Servier模式,必须需要这四个:
(比喻为打电话模式:手机A-通讯录-电话基站-手机B
Client(客户端)-ServiceManager-Binder驱动-Server端

Binder的通信实现方式:
1.首先需要注册服务端,只有注册了服务端,客户端才有通讯的目标,服务端通过 ServiceManager 注册服务,注册的过程就是向 Binder 驱动的全局链表( binder_procs) 中插入服务端的信息(binder_proc 结构体,每个 binder_proc 结构体中都有 todo 任务队列),然后向 ServiceManager 的 svcinfo 列表中缓存一下注册的服务。
有了服务端,客户端就可以跟服务端通讯了,通讯之前需要先获取到服务,拿到服务的代理,也可以理解为引用。比如下面的代码:

//获取WindowManager服务引用
WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE);

2.获取服务端的方式就是通过 ServiceManager 向 svcinfo 列表中查询一下返回服务端的代理,svcinfo 列表就是所有已注册服务的通讯录,保存了所有注册的服务信息。

3.有了服务端的引用我们就可以向服务端发送请求了,通过 BinderProxy 将我们的请求参数发送给 ServiceManager,通过共享内存的方式使用内核方法 copy_from_user() 将我们的参数先拷贝到内核空间,这时我们的客户端进入等待状态,然后 Binder 驱动向服务端的 todo 队列里面插入一条事务,执行完之后把执行结果通过 copy_to_user() 将内核的结果拷贝到用户空间(这里只是执行了拷贝命令,并没有拷贝数据,binder只进行一次拷贝),唤醒等待的客户端并把结果响应回来,这样就完成了一次通讯。

image.png

你可能感兴趣的:(Binder详解)