今天说说神秘又常用又多变的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. PowerShell查看历史记录

    PowerShell的所有历史记录:   Get-Content (Get-PSReadLineOption).HistorySavePath   顺手写了一个掉用的函数:  function Get ...

  2. mysql自动化建表脚本

    主脚本 配置文件 执行结果 主脚本内容 由于在awk中用常规方法无法转译单引号,所以用了单引号的八进制编码进行转译代替\047 等价于 ' [root@hadoop01 data]# cat crea ...

  3. CSS动画之过渡模块

    :hover伪类选择器可以用于所有的选择器(只有在悬停时,执行选择器的属性)CSS3中新增过渡模块:transition property(属性)duration(过渡效果花费的时间)timing-f ...

  4. 基于Vue.js PC桌面端弹出框组件|vue自定义弹层组件|vue模态框

    vue.js构建的轻量级PC网页端交互式弹层组件VLayer. 前段时间有分享过一个vue移动端弹窗组件,今天给大家分享一个最近开发的vue pc端弹出层组件. VLayer 一款集Alert.Dia ...

  5. mysql处理数据库事务

    数据库事务 关注公众号"轻松学编程"了解更多. 1.概念 ​ 执行批量操作时,这些操作作为一个整体,要么全部成功,要么全部失败.如银行转账,己方扣钱.对方加钱,这两个操作是一个整体 ...

  6. 记EF的一个基本访问类

    代码: 1 using EFModel; 2 using System; 3 using System.Collections.Generic; 4 using System.Data.Entity; ...

  7. linux下的终端利器----tmux

    转:tmux 是指通过一个终端登录远程主机并运行后,在其中可以开启多个控制台的终端复用软件.类似GNU Screen,但来自于OpenBSD,采用BSD授权.使用它最直观的好处就是,通过一个终端登录远 ...

  8. leetcode25word-ladder

    题目描述 给定两个单词(初始单词和目标单词)和一个单词字典,请找出所有的从初始单词到目标单词的最短转换序列的长度: 每一次转换只能改变一个单词 每一个中间词都必须存在单词字典当中 例如: 给定的初始单 ...

  9. Metasploitable3学习笔记--永恒之蓝漏洞复现

    漏洞描述: Eternalblue通过TCP端口445和139来利用SMBv1和NBT中的远程代码执行漏洞,恶意代码会扫描开放445文件共享端口的Windows机器,无需用户任何操作,只要开机上网,不 ...

  10. mysql char varchar

    摘自:http://dev.mysql.com/doc/refman/5.6/en/char.html In contrast to CHAR, VARCHAR values are stored a ...