¿Conoces Android Binder?

Este es el día 15 de mi participación en el Desafío de actualización de noviembre. Para obtener detalles del evento, consulte: Desafío de última actualización de 2021

prefacio

Binder es uno de los métodos de comunicación entre procesos (IPC) del sistema Android. La comunicación entre procesos IPC significa que Linux ya incluye (Conexión de proceso de Internet): canalización (Pipe), señal (Signal) y seguimiento (Trace), socket (Socket), cola de mensajes (Message), memoria compartida (Share Memory) y Semáforo.

1. El papel del encuadernador

El mecanismo de Binder juega un papel fundamental en Android, y muchos de los principios que debemos dominar están relacionados con Binder:\

  • Comunicación de varias claves de proceso en el sistema
  • Proceso de inicio del sistema Android
  • Principios de AMS y PMS
  • El principio de los cuatro componentes (como el inicio de la Actividad)
  • Principio de complemento
  • El principio de comunicación entre el lado del cliente y el lado del servidor del servicio del sistema (como MediaPlayer y MediaPlayerService)

2. Por qué usar Binder

ventaja

1. Rendimiento En los dispositivos móviles (dispositivos con un rendimiento limitado, como el ahorro de energía), el uso extensivo de la comunicación entre procesos tiene requisitos estrictos sobre el rendimiento del mecanismo de comunicación En comparación con el método Socket tradicional, Binder es más eficiente. La copia de datos de Binder solo necesita una vez, mientras que la canalización, la cola de mensajes y el Socket necesitan dos veces. El método de memoria compartida no necesita una copia de memoria, pero el método de implementación es más complicado.

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

31fb00576efe485145a1df33fd63615a.png

Binder的原理

IPC机制简单描述

imagen.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 对线程的管理

Cada proceso del servidor de Binder creará muchos subprocesos para procesar las solicitudes de Binder, lo que puede entenderse simplemente como la creación de un grupo de subprocesos de Binder (aunque en realidad no es un método de gestión de subprocesos tan simple), y la gestión real de estos subprocesos no lo es. administrado por el lado del servidor, pero administrado por el controlador de Binder.
El número máximo predeterminado de subprocesos de Binder en un proceso es 16, y las solicitudes en exceso se bloquearán en espera de subprocesos de Binder inactivos. Si entiende esto, tendrá una base para lidiar con los problemas de concurrencia cuando realice una comunicación entre procesos. Por ejemplo, cuando use ContentProvider (otro componente que usa el mecanismo Binder), sabrá su CRUD (crear, recuperar, actualizar y eliminar) El método solo puede tener 16 subprocesos ejecutándose al mismo tiempo.

Escenarios de aplicación

Bueno, ahora que se ha entendido el mecanismo de Binder, echemos un vistazo a cómo Android usa Binder. Reproducir el código anterior:

//获取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); El principio interno de la función es consultar al ServiceManager la referencia del objeto remoto cuyo identificador es getApplication().WINDOW_SERVICE. Es decir, la referencia del objeto WindowManager, la implementación real de esta referencia es un proxy del WindowManager. Después de obtener esta referencia, al llamar a addView, la implementación real está en el proxy. El proxy empaqueta los parámetros en el objeto Parcel, luego llama a la función de transacción (esta función se hereda de Binder) y luego desencadena una serie de procesos de llamada impulsados ​​por Aglutinante.

Resumir

El problema de multiproceso no se encuentra en todos los desarrollos. Muchas aplicaciones solo necesitan completar los requisitos comerciales en su propio proceso. Sin embargo, si conocemos la existencia de multiproceso y entendemos el mecanismo Binder proporcionado por Android, entonces estamos eligiendo cómo hacer el proceso La interacción será más clara sobre posibles problemas y soluciones de Android.

Supongo que te gusta

Origin juejin.im/post/7031526762299424805
Recomendado
Clasificación