神秘、常用、多变的Binder
今天说说神秘又常用又多变的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的更多相关文章
- Android 综合揭秘 —— 全面剖释 Service 服务
引言 Service 服务是 Android 系统最常用的四大部件之一,Android 支持 Service 服务的原因主要目的有两个,一是简化后台任务的实现,二是实现在同一台设备当中跨进程的远程信息 ...
- [转]Android Binder设计与实现 - 设计篇
摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder ...
- GJM : 常用网站收集 【不断更新中... ... ... 】
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- Struts2常用标签
Struts2常用标签总结 一 介绍 1.Struts2的作用 Struts2标签库提供了主题.模板支持,极大地简化了视图页面的编写,而且,struts2的主题.模板都提供了很好的扩展性.实现了更好的 ...
- 揭开Sass和Compass的神秘面纱
揭开Sass和Compass的神秘面纱 可能之前你像我一样,对Sass和Compass毫无所知,好一点儿的可能知道它们是用来作为CSS预处理的.那么,今天请跟我一起学习下Sass和Compass的一些 ...
- Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc
Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc 1. #-------常用 游戏类型 1 2. 街机的历史 2 3. #=========== ...
- (转)Android Binder设计与实现 – 设计篇
原文地址(貌似已打不开):Android Binder设计与实现 – 设计篇 ------------------------------------------------------------- ...
- Android源码剖析之Framework层基础版(窗口、linux、token、Binder)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 关于Framework,就是应用层底下的控制层,离应用层最近,总想找个机会,写写WindowMang ...
- J2EE开发之常用开源项目介绍
主要就我所了解的J2EE开发的框架或开源项目做个介绍,可以根据需求选用适当的开源组件进行开发.主要还是以Spring为核心,也总结了一些以前web开发常用的开源工具和开源类库 1持久层: 1)Hibe ...
随机推荐
- Spring In Action 5th中的一些错误
引言 最近开始学习Spring,了解到<Spring实战>已经出到第五版了,遂打算跟着<Spring实战(第五版)>来入门Spring,没想到这书一点也不严谨,才看到第三章就发 ...
- salesforce零基础学习(九十七)Big Object
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.224.0.bigobjects.meta/bigobjects/async_query ...
- image restoration(IR) task
一般的,image restoration(IR)任务旨在从观察的退化变量$y$(退化模型,如式子1)中,恢复潜在的干净图像$x$ $y \text{} =\text{}\textbf{H}x\tex ...
- 云计算之路-出海记:蹭一张 aws 船票
出海记开篇之后,在 aws 上搭建博客园海外站的出海计划今天开始迈出第一步 -- 注册一个 aws 海外区域账号. aws 现在针对新注册用户提供12个月免费套餐(正在园子里推广并提供了专属注册通道) ...
- 【CF1445D】Divide and Sum 题解
题目链接 题意简介 将一个长度为 2n 的数列平均分为两个子数列 p 和 q 后,p 按从小到大排序,q 按从大到小排序. 排序后,记 p 为 \(\{x_i\}\) ,q 为 \(\{y_i\}\) ...
- redis方法-
//链接错误注意 //1.防火墙 //2.配置文件IP绑定 $redis = new Redis(); //连接redis $redis->connect('127.0.0.1', 6379); ...
- 【Flutter 实战】pubspec.yaml 配置文件详解
老孟导读:pubspec.yaml 文件是 Flutter 中非常重要的配置文件,下面就让我们看看里面各个配置的含义. pubspec.yaml 是 Flutter 项目的配置文件,类似于 Andro ...
- Vue的生命周期--代码片段
Vue 实例有一个完整的生命周期,也就是从开始创建. 初始化数据. 编译模板. 挂载 Dom. 渲染→更新→渲染. 销毁等一系列过程,我们称这是 Vue 的生命周期.通俗说就是 Vue 实例从创建到销 ...
- 汉诺塔问题实验--一个简洁的JAVA程序
思路: 这里使用递归法 n==1的时候,直接把它从x移到z位置即可. 如果是n层,我们首先把上面的n- 1层移到y位置,然后把最 下面的那个最大的盘子,移到z位置,然后把y上面放的上面n-1层移到z位 ...
- linux + MongoDB 安装 + 部署 + 讲解 (满满干货看完记得收藏噢)
话不多说开始了! 安装 安装就依据菜鸟教程的进行安装 传送门 => https://www.runoob.com/mongodb/mongodb-linux-install.html 好啦!现在 ...