Do you know Android Binder?

This is the 15th day of my participation in the November Update Challenge. For details of the event, please check: 2021 Last Update Challenge

foreword

Binder is one of the Android system inter-process communication (IPC) methods. The inter-process communication IPC means that Linux already has include (Internet Process Connection): pipeline (Pipe), signal (Signal) and trace (Trace), socket (Socket), message queue (Message), shared memory (Share Memory) and Semaphore.

1. The role of Binder

The Binder mechanism plays a pivotal role in Android, and many of the principles we need to master are related to Binder:\

  • Communication of various process keys in the system
  • Android system startup process
  • Principles of AMS and PMS
  • The principle of the four components (such as the start of Activity)
  • Plug-in principle
  • The communication principle between the client side and the server side of the system service (such as MediaPlayer and MediaPlayerService)

2. Why use Binder

advantage

1. Performance On mobile devices (devices with limited performance, such as power saving), the extensive use of cross-process communication has strict requirements on the performance of the communication mechanism. Binder is more efficient than the traditional Socket method. The Binder data copy only needs one time, while the pipeline, message queue, and Socket all need two times. The shared memory method does not need a memory copy, but the implementation method is more complicated.

2、安全方面     首先传统IPC的接收方无法获得对方进程可靠的UID和PID(用户ID进程ID),从而无法鉴别对方身份。Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。其实Binder机制主要是在本机内进行跨进程通信,而socket等IPC方式主要是用于跨网络的通信手段,因而socket不能限制了入口和出口,所以从使用场景来看,socket给用户提供的使用范围更广,而binder由于为了保证它的数据安全性,必须限制于android系统的机子中,而且在内核中就已经对UID进行了验证。 用一张图来展示Binder在Android 启动过程中的作用如下:

31fb00576efe485145a1df33fd63615a.png

Binder的原理

IPC机制简单描述

image.png

每个Android的进程,只能运行在自己进程所拥有的虚拟地址空间。对应一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间,当然内核空间的大小是可以通过参数配置调整的。对于用户空间,不同进程之间彼此是不能共享的,而内核空间却是可共享的。Client进程向Server进程通信,恰恰是利用进程间可共享的内核内存空间来完成底层通信工作的,Client端与Server端进程往往采用ioctl等方法跟内核空间的驱动进行交互。

Binder框架定义了四个角色:Server,Client,ServiceManager(以后简称SMgr)以及Binder驱动。其中Server,Client,SMgr运行于用户空间,驱动运行于内核空间。这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,SMgr是域名服务器(DNS),驱动是路由器。

1 Binder 驱动和路由器一样,Binder驱动虽然默默无闻,却是通信的核心。尽管名叫‘驱动’,实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是一样的。它工作于内核态,驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。

2 ServiceManager 与实名Binder和DNS类似,SMgr的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对Server中Binder实体的引用。注册了名字的Binder叫实名Binder,就象每个网站除了有IP地址外还有自己的网址。Server创建了Binder实体,为其取一个字符形式,可读易记的名字,将这个Binder连同名字以数据包的形式通过Binder驱动发送给SMgr,通知SMgr注册一个名叫张三的Binder,它位于某个Server中。驱动为这个穿过进程边界的Binder创建位于内核中的实体节点以及SMgr对实体的引用,将名字及新建的引用打包传递给SMgr。SMgr收数据包后,从中取出名字和引用填入一张查找表中。细心的读者可能会发现其中的蹊跷:SMgr是一个进程,Server是另一个进程,Server向SMgr注册Binder必然会涉及进程间通信。当前实现的是进程间通信却又要用到进程间通信,这就好象蛋可以孵出鸡前提却是要找只鸡来孵蛋。Binder的实现比较巧妙:预先创造一只鸡来孵蛋:SMgr和其它进程同样采用Binder通信,SMgr是Server端,有自己的Binder对象(实体),其它进程都是Client,需要通过这个Binder的引用来实现Binder的注册,查询和获取。SMgr提供的Binder比较特殊,它没有名字也不需要注册,当一个进程使用BINDER_SET_CONTEXT_MGR命令将自己注册成SMgr时Binder驱动会自动为它创建Binder实体(这就是那只预先造好的鸡)。其次这个Binder的引用在所有Client中都固定为0而无须通过其它手段获得。也就是说,一个Server若要向SMgr注册自己Binder就必需通过0这个引用号和SMgr的Binder通信。类比网络通信,0号引用就好比域名服务器的地址,你必须预先手工或动态配置好。要注意这里说的Client是相对SMgr而言的,一个应用程序可能是个提供服务的Server,但对SMgr来说它仍然是个Client。

3 Client 获得实名Binder的引用Server向SMgr注册了Binder实体及其名字后,Client就可以通过名字获得该Binder的引用了。Client也利用保留的0号引用向SMgr请求访问某个Binder:我申请获得名字叫张三的Binder的引用。SMgr收到这个连接请求,从请求数据包里获得Binder的名字,在查找表里找到该名字对应的条目,从条目中取出Binder的引用,将该引用作为回复发送给发起请求的Client。从面向对象的角度,这个Binder对象现在有了两个引用:一个位于SMgr中,一个位于发起请求的Client中。如果接下来有更多的Client请求该Binder,系统中就会有更多的引用指向该Binder,就象java里一个对象存在多个引用一样。而且类似的这些指向Binder的引用是强类型,从而确保只要有引用Binder实体就不会被释放掉。通过以上过程可以看出,SMgr象个火车票代售点,收集了所有火车的车票,可以通过它购买到乘坐各趟火车的票-得到某个Binder的引用。

4 匿名 Binder并不是所有Binder都需要注册给SMgr广而告之的。Server端可以通过已经建立的Binder连接将创建的Binder实体传给Client,当然这条已经建立的Binder连接必须是通过实名Binder实现。由于这个Binder没有向SMgr注册名字,所以是个匿名Binder。Client将会收到这个匿名Binder的引用,通过这个引用向位于Server中的实体发送请求。匿名Binder为通信双方建立一条私密通道,只要Server没有把匿名Binder发给别的进程,别的进程就无法通过穷举或猜测等任何方式获得该Binder的引用,向该Binder发送请求。

四、Binder 对线程的管理

Each Binder server process will create many threads to process Binder requests, which can be simply understood as creating a Binder thread pool (although it is not actually such a simple thread management method), and the real management of these threads does not It is not managed by the server side, but managed by the Binder driver.
The default maximum number of Binder threads in a process is 16, and the excess requests will be blocked waiting for idle Binder threads. If you understand this, you will have a foundation for dealing with concurrency issues when you do inter-process communication. For example, when using ContentProvider (another component that uses the Binder mechanism), you will know its CRUD (create, retrieve, update and delete) The method can only have 16 threads running at the same time.

Application scenarios

Well, now that the Binder mechanism has been understood, let's take a look at how Android uses Binder. Reproduce the previous code:

//获取WindowManager服务引用
WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE);  
//布局参数layoutParams相关设置略...
View view=LayoutInflater.from(getApplication()).inflate(R.layout.float_layout, null);  
//添加view
wm.addView(view, layoutParams);

复制代码

getSystemService(getApplication().WINDOW_SERVICE); The internal principle of the function is to query the ServiceManager for the reference of the remote object whose identifier is getApplication().WINDOW_SERVICE. That is, the reference of the WindowManager object, the real implementation of this reference is a proxy of the WindowManager. After getting this reference, when calling addView, the real implementation is in the proxy. The proxy packs the parameters into the Parcel object, then calls the transact function (this function inherits from Binder), and then triggers a series of calling processes driven by Binder.

Summarize

The problem of multi-process is not encountered in every development. Many applications only need to complete the business requirements in their own process. However, if we know the existence of multi-process and understand the Binder mechanism provided by Android, then we are choosing how to do the process. The interaction will be more clear about possible problems and Android solutions.

Guess you like

Origin juejin.im/post/7031526762299424805