安卓学习嵌牛IT观察

通过一张图来学习安卓的binder机制

2019-02-20  本文已影响0人  小怪兽大作战

一、什么是binder

binder从不同的角度来说有不同的解释

1.首先从功能上来说,binder是安卓中特有的一种跨进程通信机制。由于在用户空间中不同的进程有着不同的内存地址,他们之间需要binder来架起通信的桥梁

image.png

2.从系统内核层面来说,binder是运行在linux内核中的一个动态内核

3.binder也是安卓的一个类,实现IBinder接口

4.对于在FrameWork层的serviceManager来说,binder是serviceManager连接各种service的纽带

5.在应用层,binder也是c/s模式 ,分为客户端和服务端

二、下面,我们就从一张图来学习binder,上图!

image.png

上图中我将安卓系统分为三个部分,内核层,FrameWork层,应用层。里面有几个重要的概念内核空间中的binder驱动,内存映射和binder_procs全局链表;FrameWork的serviceManager;应用层的客户端和服务端。下面我们来一个一个学习这些重要的概念。

内核空间

内核空间运行着Linux的内核,用户空间运行用户的程序。为了系统的安全,内核空间和用户空间是相互隔离的。用户空间访问内核空间的唯一方法就是系统调用。

binder驱动

在 Android 系统中,这个运行在内核空间,负责各个用户进程通过 Binder 实现通信的内核模块就叫 Binder 驱动(Binder Dirver)。Binder并不是原生Linux内核的东西,是通过Linux的动态可加载模块机制运行在Linux内核中的。

内存映射

内存映射简单的说就是将用户空间的一块内存映射到内核空间。映射关系建立后,用户对这块内存的操作会直接反应到内核中,内核对这块区域的操作也会直接反应到用户空间中。

binder_procs全局链表

这个链表保存在内核中,链表中存储着所有已经注册的binder服务的信息

serviceManager

service_manager是在系统初始化的时候启动的进程,是binder驱动的守护进程。service_manager向用户层提供查询binder服务和注册binder服务的功能,是binder的大管家。

svcinfo

在这个里面保存着所有已经注册的binder服务的代理,所谓代理意思是这个代理不是真的binder服务,只是与binder服务有着相同的接口,客户端使用该接口可以访问服务端实现的功能。

服务端

服务端实现stub类,这个类继承binder,实现了服务端和客户端约定好的功能接口(我们暂定这个功能接口是myInterface)。

客户端

客户端查询到服务后会获得相应服务的代理,使用这个代理就可以访问服务端的实现的功能。

三、binder通信大致流程

了解了Binder通信过程中的一些关键概念,我们来学习一下binder通信的流程。
首先binder服务端向ServiceManager发出注册服务请求,ServiceManager与内核空间的binder驱动相互配合,完成binder服务端注册,并将binder服务的信息保存到内核空间的binder_procs全局链表中,将binder服务的代理保存到svcinfo中。
绑定过binder服务后,客户端就可以访问服务了。首先客户端应该向service_manager发出获取服务的请求,service_manager在binder驱动的帮助下从scvinfo中查询相应服务的代理,返回代理。客户端拿到代理之后,通过调用代理中的接口,在binder驱动的帮助下完成进程间通信(通过内存映射的方式)

四、注册binder服务的流程

image.png

1.服务端向service_manager发出注册服务的请求
2.service_manager向binder驱动发出注册服务的请求
3.binder驱动相应请求,将被注册的服务信息保存到内核中的binder_procs全局链表中
4.binder驱动返回被注册服务的代理
5.service_manager将服务的代理保存到svcinfo中
6.返回到服务端

五、客户端获取服务

image.png

1.客户端向service_manager发出获取服务请求
2.service_manager在binder驱动的帮助下查询驱动,在svcinfo中查询驱动代理
3.给客户端返回驱动代理

六、客户端使用服务代理与服务端进行通信

image.png

1.服务端调用代理中的接口,输入参数
2.binder驱动分别在在内核空间和服务端开辟缓存区,建立服务端和内核空间的内存映射。使用copyfromuser将参数从用户空间复制到内核空间中的缓存区。服务端读取缓存区数据,计算结果,将结果写道缓存区中。binder驱动使用copytouser将结果返回给客户端。
3.客户端接收到结果,完成通信。

看了两天的博客,才有一点自己的总结。如果你发现有什么不对,欢迎留言。加油加油加油!

上一篇下一篇

猜你喜欢

热点阅读