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

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

Binder是什么

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

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

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

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

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

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

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

不管是获取其他的系统服务,亦或是服务端和客户端的通信,都是源于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方式。

参考

https://www.cnblogs.com/hustcser/p/10228843.html

拜拜

有一起学习的小伙伴可以关注下️我的公众号——码上积木,每天剖析一个知识点,我们一起积累知识。

神秘、常用、多变的Binder的更多相关文章

  1. Android 综合揭秘 —— 全面剖释 Service 服务

    引言 Service 服务是 Android 系统最常用的四大部件之一,Android 支持 Service 服务的原因主要目的有两个,一是简化后台任务的实现,二是实现在同一台设备当中跨进程的远程信息 ...

  2. [转]Android Binder设计与实现 - 设计篇

    摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder ...

  3. GJM : 常用网站收集 【不断更新中... ... ... 】

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  4. Struts2常用标签

    Struts2常用标签总结 一 介绍 1.Struts2的作用 Struts2标签库提供了主题.模板支持,极大地简化了视图页面的编写,而且,struts2的主题.模板都提供了很好的扩展性.实现了更好的 ...

  5. 揭开Sass和Compass的神秘面纱

    揭开Sass和Compass的神秘面纱 可能之前你像我一样,对Sass和Compass毫无所知,好一点儿的可能知道它们是用来作为CSS预处理的.那么,今天请跟我一起学习下Sass和Compass的一些 ...

  6. Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc

    Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc 1. #-------常用 游戏类型 1 2. 街机的历史 2 3. #=========== ...

  7. (转)Android Binder设计与实现 – 设计篇

    原文地址(貌似已打不开):Android Binder设计与实现 – 设计篇 ------------------------------------------------------------- ...

  8. Android源码剖析之Framework层基础版(窗口、linux、token、Binder)

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 关于Framework,就是应用层底下的控制层,离应用层最近,总想找个机会,写写WindowMang ...

  9. J2EE开发之常用开源项目介绍

    主要就我所了解的J2EE开发的框架或开源项目做个介绍,可以根据需求选用适当的开源组件进行开发.主要还是以Spring为核心,也总结了一些以前web开发常用的开源工具和开源类库 1持久层: 1)Hibe ...

随机推荐

  1. centos 8 集群Linux环境搭建

    一.集群Linux环境搭建 1. 注意事项 1.1 windows系统确认所有的关于VmWare的服务都已经启动 打开任务管理器->服务,查看五个VM选项是否打开. 1.2 确认好VmWare生 ...

  2. pychartdir模块安装

    python模块pychartdir导入问题 在迁移别人写好的脚本时,发现pychartdir没有导入,脚本执行报错.以下是报错内容: [modps@LGJF-ZYC5-MMSC-WEB02 ~]$ ...

  3. Docker知识总结

    目录 1 安装docker 2 docker基本概念 2.1 Docker是容器化平台 2.2 Docker体系结构 2.3 容器与镜像 3 docker常用命令 3.1 快速安装tomcat 3.1 ...

  4. ssh免密登陆 2

    应用场景之一:java 程序调用shell脚本,通过ssh 免密登陆数据库服务器,进行数据的抽取打包工作. 免密设置步骤: 1.客户端生成公私钥,在任意目录下执行命令ssh-keygen(一路回车默认 ...

  5. nginx tp5配置

    location ~ [^/]\.php(/|$) { #fastcgi_pass remote_php_ip:9000; fastcgi_pass unix:/dev/shm/php-cgi.soc ...

  6. 线程池FixedThreadPool

    可重用线程池,只有核心线程,并发无阻塞, public class MainActivity extends AppCompatActivity { @Override protected void ...

  7. 将字符串反转的 Java 方法

    Java中经常会用到将字符串进行反转的时候,程序员孔乙己总结了7种反转方法,如下: //方法1 递归方法 public static String reverse1(String s) { int l ...

  8. uni-app h5端跨域问题解决

    例如我现在的项目运行在 http://localhost:8080,而我有个接口是 https://service.picasso.adesk.com/v1/wallpaper/album,发起请求就 ...

  9. ERP收付款的操作与设计--开源软件诞生22

    赤龙ERP收款付款讲解--第22篇 用日志记录"开源软件"的诞生 [进入地址 点亮星星]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/redra ...

  10. win10安装linux子系统(wsl)

    win10安装linux子系统(wsl) 1.打开Microsoft Store 方式一:在电脑左下角打开 方式二:在电脑左下角的搜索里里输入Microsoft Store 打开Microsoft S ...