IPC

IPC为 (Inter-Process Communication) 缩写,称为进程间通信或跨进程通信,指两个进程间进行数据交换的过程。安卓中主要采用 Binder 进行进程间通信,当然也支持其他 IPC 方式,如:管道,Socket,文件共享,信号量等。

Binder简介

1.为什么使用Binder?

性能方面:

在移动设备上(性能受限制的设备,比如要省电),广泛地使用跨进程通信对通信机制的性能有严格的要求,Binder相对于传统的Socket方式,更加高效。Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式又比较复杂。

安全方面:

传统的进程通信方式对于通信双方的身份并没有做出严格的验证,比如 Socket 通信的IP地址是客户端手动填入,很容易进行伪造。然而,Binder机制从协议本身就支持对通信双方做身份校检,从而大大提升了安全性。

2.Binder原理

​ 从进程角度来看IPC(Interprocess Communication)机制

每个Android的进程,只能运行在自己进程所拥有的虚拟地址空间。例如,对应一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间。当然内核空间的大小是可以通过参数配置调整的。对于用户空间,不同进程之间是不能共享的,而内核空间却是可共享的。Client进程向Server进程通信,恰恰是利用进程间可共享的内核内存空间来完成底层通信工作的。Client端与Server端进程往往采用ioctl等方法与内核空间的驱动进行交互。

Binder通信采用C/S架构,从组件视角来说,包含Client、Server、ServiceManager以及Binder驱动,其中ServiceManager用于管理系统中的各种服务。架构图如下所示:

Binder通信的四个角色

Client进程:使用服务的进程。
Server进程:提供服务的进程。
ServiceManager进程

ServiceManager 的作用是将字符形式的 Binder 名字转化成 Client 中对该 Binder 的引用,使得 Client 能够通过 Binder 名字获得对 Server中Binder 实体的引用。

Binder驱动

​ 驱动负责进程之间 Binder 通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。

3.Binder间数据传递

进程间数据传递都是需要序列化的。Serializable 和 Parcelable 接口都可以完成序列化,通过 Intent 和 Binder传输数据时候就需要使用 Serializable 和 Parcelable 。

区别和联系:

Serializable 是 Java中提供的接口,序列化和反序列化需要大量的 I/O 操作,开销比较大。而 Parcelable 是安卓中的序列化方式,效率高。Parcelable 主要用在内存序列化上,Serializable 主要用在用于文件,网络中传递。

Binder

Binder 是 Android 中的一个类,实现了 IBinder 接口。

从 IPC 角度来说

Binder 是 Android 中的一种跨进程通信方式,可以理解为一种虚拟的物理设备,它的设备驱动为 /dev/binder。

从 Framework 的角度:

Binder 是 ServiceManager 连接各种 Manager(ActivityManager,WindowManager) 和 ManagerService 的桥梁。

从应用层的角度

Binder 是客户端和服务端进行通信的媒介,当 bindService 时,服务端会返回一个包含了服务端业务调用的 Binder 对象,通过这个 Binder 对象,客户端就可以获取服务端提供的服务或者数据,包括普通服务和 AIDL 服务。

1.接口关键方法分析

  • DESCRIPTOR

​ Binder 的唯一标识,一般用当前Binder的类名标识。

  • asInterface(android.os.IBinder obj)

用于将服务端返回的 Binder 对象转换成客户端所需要的 AIDL 接口类型的对象,注意:如果 Client 和 Service 位于统一进程,该方法返回的就是 Service 的 Stub 对象本身,否则返回的是系统封装后的 Stub.proxy 代理的对象。

  • asBinder 返回当前 Binder 对象
  • onTransact

这个方法运行在 Service 中的 Binder 线程池中,当 Client 发起跨进程请求时,远程请求会通过系统底层封装后交由该方法类处理。服务端通过 code 来确定 Client 调用的具体是哪个方法,然后从 data 中取出方法对应的入参,然后执行目标方法。当目标方法执行完后,向 reply 中写入执行结果。注意:如果该方法返回false,则 Client 的请求会失败,可以利用这个特征来做权限验证(权限验证失败,返回false)。

小结:

客户端发起远程请求时,由于当前线程会被挂起直至服务端进程返回数据,所以如果一个远程方法是很耗时的,那么不能在 UI 线程中发起次远程请求。

服务端的 Binder 方法时运行在 Binder 线程池中的,所以 Binder 中的方法无论是否耗时都应该采用同步的方式去实现。

2.linkToDeath 和 unLinkToDeath

Binder 运行在服务端进程,如果服务端进程异常终止,会导致远程调用失败。Binder 中提供了两个配对的方法 linkToDeathunLinkToDeath,通过 linkToDeath 可以为 Binder 设置一个死亡代理,当Binder死亡时,会收到通知,这个时候可以重新发起连接请求从而恢复连接。

3.Android中IPC方式

1.使用 Bundle

Bundle 实现了 Parcelable 接口,可以通过 Intent 进行传递。当从一个进程启动另一个进程的 Activity 时,可以在 Bundle 中附加参数,这些数据必须是能够被序列化的。

2.使用文件共享

A进程往文件中写数据,B进程从文件中读数据。在 Windows上,一个文件如果被加了排斥锁将会导致其他线程无法对其进行访问。而 Andorid 是基于 Linux,是的其支持并发 读/写 可以无限制的进行,但是需要注意并发安全问题。

SharedPreferences 是 Android中轻量级的存储方案,通过键值对来存储数据,采用 xml 文件来保存键值对。因为 Android 系统对 读/写 有一定的缓存策略,即在内存中会有一份 SharedPreferences 文件的缓存,在多进程下,系统对它的读写变得不可靠。SharedPreferences 的 get 个 put 方法都是经过 synchronized 修饰的。

3.使用 Messenger

Messenger 也被翻译为信使,通过它可以在不同的进程间传递 Message 对象,在 Message 中放入我们需要传递的数据。它的底层也是常用 AIDL。

服务端通过 Handler 创建一个 Messenger,然后在 Servce 的 onBind 方法中返回这个 Messenger 对象的底层的 Binder即可。客户端通过服务端返回的 IBinder 就可以创建 Messenger来服务端发消息了。

4.使用 AIDL

在 AIDL 接口文件中的方法中有 in,out,inout 三个前缀参数

  • in 表示输入型参数
  • out 表示输出型参数
    inout 表示输入输出型参数

注意:

因为跨进程数据传输是要经过序列化和反序列化的过程,在客户端中注册的 listener 和 服务端中收到的 listener 不是同一个对象,在进行接口反注册的时候,会出现失败(因为它们根本不是同一个对象)。可以系统提供的 RemoteCallbackList 集合。RemoteCallbackList内部有 一个 Map集合。

RemoteCallbackList 在当客户端进程终止掉后,它能自动移除客户端所注册的 listener。另外,RemoteCallbackList 内部自动实现线程同步的功能。当然,也可以采用JUC包下的map结合来管理 listener,key 为客户端进程的 id。

上面讲到 Binder方法时运行在 Binder线程池中的,客户端在远程请求时会挂起,因避免在 UI 线程发起跨进程的远程调用。同理,当服务端调用客户端的 listener 中的方法时候,客户端被调用的方法也运行在 Binder 线程池中,所以尽量避免在服务端中直接调用客户端 listener 中的耗时方法。否则会导致服务端无响应。

5.使用 ContentProvider

​ ContentProvider 是 Android 提供的专门用于不同应用间进行数据共享的方式,它的底层实现也是 Binder。

6.使用 Socket

​ Socket 也被称为 “套接字”,分为流式套接字和用户数据报套接字两种,分别对应于网络传输控制层中的 TCP 和 UDP协议。

IPC各种方式比较

Binder连接池

当业务中需要定义多个 AIDL 接口服务时候,可以考虑用一个服务来关闭。否则为每个 AIDL 接口定义一个服务时非常不理想的。需要将所有的 AIDL 放在同一个 Service 中去管理。

每个业务模块创建自己的 AIDL 接口并实现次接口,不同业务模块之间不能有耦合,所实现的细节要单独开来。然后向服务端提供自己的唯一标识和其对应的 Binder 对象。服务端只需要一个 Service,服务端提供了 queryBinder接口,根据接口的参数返回相应的 Binder 对象,不同的业务模块拿到所需的Binder对象就可以进行远程方法调用了。

Android进程间通信总结相关推荐

  1. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路(1)

    上一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划简要介绍了Android系统进程间通信机制Binder的总体架构,它由Client.Server.Service Mana ...

  2. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

    原文地址: http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信(IPC)机制Binder简要介绍和学 ...

  3. Android进程间通信(IPC)机制Binder简要介绍和学习计划

    在Android系统中,每一个应用程序都是由一些Activity和Service组成的,这些Activity和Service有可能运行在同一个进程中,也有可能运行在不同的进程中.那么,不在同一个进程的 ...

  4. Android 进程间通信——AIDL

    代码地址如下: http://www.demodashi.com/demo/12321.html 原文地址:http://blog.csdn.net/vnanyesheshou/article/det ...

  5. Android进程间通信 - 几种方式的对比总结

    文章目录 什么是RPC 什么是IPC 参考 什么是RPC RPC(Remote Procedure Call)即远程过程调用,它是一种通过网络从远程计算机程序上请求服务,在不需要了解底层网络技术的协议 ...

  6. Android 进程间通信之管道 - pipe

    文章目录 Android 进程间通信专栏 linux支持的进程间通信 管道 - pipe 概要 配置环境 android 系统中使用管道的场景 Android 进程间通信专栏 linux支持的进程间通 ...

  7. Android 进程间通信 实例分析

    Android Service是分为两种: 本地服务(Local Service): 同一个apk内被调用 远程服务(Remote Service):被另一个apk调用   远程服务需要借助AIDL来 ...

  8. Android进程间通信

    一.Linux系统进程间通信有哪些方式? 1.socket: 2.name pipe命名管道: 3.message queue消息队列: 4.singal信号量: 5.share memory共享内存 ...

  9. android进程间通信:使用AIDL

    android 的binder其实是基于 openbinder实现的,openbinder的地址:http://www.angryredplanet.com/~hackbod/openbinder/d ...

  10. Android 进程间通信

    要讲 Android 进程通信的话,就不得不先讲讲 Service. Service 是 Android 的四大组件之一,它主要的作用是后台执行操作,Activity 属于带有 UI 界面跟用户进行交 ...

最新文章

  1. 分离硬件和代码、稳定 API,PyTorch Lightning 1.0.0 版本正式发布
  2. BZOJ2055 80人环游世界
  3. [Javascipt] Immediately-Invoker 2
  4. 从面向过程到面向对象
  5. mysql 插入数据时,出现\xF0\x5F\x6F\x70问题
  6. python训练数据集_Python-yolov3训练自己的数据集,pytorchyolov3
  7. parted工具详解
  8. 【Python基础知识-pycharm版】第十节_异常
  9. php 变量字节大小,PHP 变量
  10. 基于HTML5的WebGL实现的2D3D迷宫小游戏
  11. 基于Netty模拟解析Binlog
  12. Tomcat启动提示At least one JAR was scanned for TLDs yet contained no TLDs
  13. Sonya and Robots(set应用)
  14. 计算机精品学习资料大放送
  15. 如何实现多源异构系统数据整合?
  16. 戴尔灵越14电脑U盘重装系统方法分享
  17. LightOJ1012-Guilty Prince
  18. 7000字,详解仓湖一体架构!
  19. 黑夜给了我黑色的眼睛,我用它来寻找黑夜
  20. ubuntu20.04里怎么创建.txt文件

热门文章

  1. 王道数据结构p41——22
  2. Python在操作系统层面上的操作
  3. SpringBoot+Vue项目线上教学平台
  4. Golang字符串拼接
  5. python生成图文并茂的pdf--财务报表(四)封面(首页和正页定义)
  6. 平面最近点对问题求解—基于Java语言
  7. VMware备份和恢复的方法
  8. 域名解析出现错误,该如何解决?
  9. axios获取html页面,axios 获取后台数据
  10. 计算机组成原理第三次实验(静态随机存储器实验)