神秘、经常使用、多变的Binder

今天说说神秘又经常使用又多变的Binder~html

  • Binder是什么
  • Binder通讯过程和原理
  • 在Android中的应用
  • Binder优点

Binder是什么

先借用神书《Android开发艺术探索》中的一段话:java

直观的说,Binder是一个类,实现了IBinder接口。

从IPC(Inter-Process Communication,进程间通讯)角度来讲,Binder是Android中一种跨进程通讯方式。

还能够理解为一种虚拟的物理设备,它的设备驱动是/dev/binder。

从Android FrameWork角度来讲,Binder是ServiceManager链接各类Manager(ActivityManager,WindowManager等等)和响应ManagerService的桥梁。

从Android应用层来讲,Binder是客户端和服务端进行通讯的媒介。

挺多概念的是吧,其实就说了一件事,Binder就是用来进程间通讯的,是一种IPC方式。后面全部的解释都是Binder实际应用涉及到的内容。android

不论是获取其余的系统服务,亦或是服务端和客户端的通讯,都是源于Binder的进程间通讯能力。安全

Binder通讯过程和原理

首先,仍是看一张图,原图也是出自神书中:服务器

首先要明确的是客户端进程是没法直接操做服务端中的类和方法的,由于不一样进程直接是不共享资源的。因此客户端这边操做的只是服务端进程的一个代理对象,也就是一个服务端的类引用,也就是Binder引用。多线程

整体通讯流程就是:函数

  • 客户端经过代理对象向服务器发送请求。
  • 代理对象经过Binder驱动发送到服务器进程
  • 服务器进程处理请求,并经过Binder驱动返回处理结果给代理对象
  • 代理对象将结果返回给客户端。

再看看在咱们应用中经常用到的工做模型,上图:工具

这就是在应用层面咱们经常使用的工做模型,经过ServiceManager去获取各类系统进程服务。这里的通讯过程以下(详细流程也可参考文末连接):性能

  • 服务端跨进程的类都要继承Binder类,因此也就是服务端对应的Binder实体。这个类并非实际真实的远程Binder对象,而是一个Binder引用(即服务端的类引用),会在Binder驱动里还要作一次映射。
  • 客户端要调用远程对象函数时,只须要调用Binder引用的方法,通常是transact函数。
  • 而后Binder引用会把数据放入到Client的共享内存,Binder驱动从Client的共享内存中读取数据,根据这些数据找到对应的远程进程的共享内存。
  • 而后把数据拷贝到远程进程的共享内存中,并通知远程进程执行onTransact()函数,这个函数也是属于Binder类。
  • 远程进程Binder对象执行完成后,将获得的写入本身的共享内存中,Binder驱动再将远程进程的共享内存数据拷贝到客户端的共享内存,并唤醒客户端线程。

因此通讯过程当中比较重要的就是这个服务端的Binder引用,经过它来找到服务端并与之完成通讯。学习

看到这里可能有的人疑惑了,图中线程池怎么没用到啊?

  • 能够从第一张图中看出,Binder线程池位于服务端,它的主要做用就是将每一个业务模块的Binder请求统一转发到远程Servie中去执行,从而避免了重复建立Service的过程。也就是服务端只有一个,可是能够处理多个不一样客户端的Binder请求。

在Android中的应用

Binder在Android中的应用除了刚才的ServiceManager,你还想到了什么呢?

  • 系统服务是用过getSystemService获取的服务,内部也就是经过ServiceManager。例如四大组件的启动调度等工做,就是经过Binder机制传递给ActivityManagerService,再反馈给Zygote。而咱们本身平时应用中获取服务也是经过getSystemService(getApplication().WINDOW_SERVICE)代码获取。
  • AIDL(Android Interface definition language)。例如咱们定义一个IServer.aidl文件,aidl工具会自动生成一个IServer.java的java接口类(包含Stub,Proxy等内部类)。
  • 前台进程经过bindService绑定后台服务进程时,onServiceConnected(ComponentName name, IBinder service)传回IBinder对象,而且能够经过IServer.Stub.asInterface(service)获取IServer的内部类Proxy的对象,其实现了IServer接口。

Binder优点

在Linux中,进程通讯的方式确定不止Binder这一种,还有如下这些:

管道(Pipe)
信号(Signal)
消息队列(Message)
共享内存(Share Memory)
套接字(Socket)
Binder

Binder在这以后主要有如下优势:

  • 性能高,效率高:传统的IPC(套接字、管道、消息队列)须要拷贝两次内存、Binder只须要拷贝一次内存、共享内存不须要拷贝内存。
  • 安全性好:接收方能够从数据包中获取发送发的进程Id和用户Id,方便验证发送方的身份,其余IPC想要实验只可以主动存入,可是这有可能在发送的过程当中被修改。

熟悉Zygote的朋友可能知道,在fork()进程的时候,也就是向Zygote进程发出建立进程的消息的时候,用到的进程间通讯方式就不是Binder了,而换成了Socket,这主要是由于fork不容许存在多线程,Binder通信恰恰就是多线程。

因此具体的状况仍是要去具体选择合适的IPC方式。

参考

http://www.javashuo.com/article/p-nfrqcdjw-nw.html

拜拜

有一块儿学习的小伙伴能够关注下❤️个人公众号——码上积木,天天剖析一个知识点,咱们一块儿积累知识。

相关文章
相关标签/搜索