首页 > 系统相关 >Android进程间通信总结

Android进程间通信总结

时间:2023-04-21 09:47:37浏览次数:55  
标签:总结 间通信 Binder Client 进程 Android 序列化 服务端 客户端

原文地址 blog.csdn.net

在这里插入图片描述

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对象就可以进行远程方法调用了。

请添加图片描述

标签:总结,间通信,Binder,Client,进程,Android,序列化,服务端,客户端
From: https://www.cnblogs.com/cps666/p/17339174.html

相关文章

  • android8 rk3399 同时支持多个USB摄像头
    文章目录一、前文二、CameraHal_Module.h三、CameraHal_Module.cpp四、编译&烧录Image五、App验证一、前文Android系统默认支持2个摄像头,一个前置摄像头,一个后置摄像头需要支持数量更多的摄像头,得修改AndroidHal层的代码二、CameraHal_Module.h修改CAMERAS_SUPPORT_MAX三、Camer......
  • 2023.4.20每日总结
    今天完成了什么:今天完成了对于数据插入时进行确认时碰到的问题,现在已经可以成功的让用户确认及修改数据以及删除数据了遇到了哪些困难:在完成昨天碰到的问题之后,紧接着就转向了根据消费类型以及消费金额来生成相应的总账单图,不知如何下手,明天打算完成这部分明天打算做什么:完成根......
  • 每日总结 4.20
    今天进行了供货商页面的设计,对于数据的处理实现对应付金额的显示,对于登录显示用户名,明天进行补货,对于每个用户发送的信息进行补货。packagequeren;importtoolse.Tool;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importj......
  • Android问题解决:android.os.FileUriExposedException: file:///storage/......Intent.
    文章目录一、遇到问题二、解决问题三、分析问题一、遇到问题---------beginningofcrash2022-12-2720:18:15.01014422-14422/com.lisi.evidence_boxE/AndroidRuntime:FATALEXCEPTION:mainProcess:com.lisi.evidence_box,PID:14422android.os.FileUriExpose......
  • 每日总结
    今天继续写教学管理系统的前台页面      ......
  • 并行计算部分总结
    1。计算机的峰值为主频x4。2。计算机读取数组时,一次会读入一行,要最大限度的利用已读入的数据,减少频繁读写的次数。3。多线程内存共享,多进程需要消息传递来交换变量。4。利用管道在不同程序之间传递内容(可以是管道符|或mkfifomypipe)5。平均不同节点的计算量,尽量做到负载平衡。6......
  • 【考后总结】4 月清北营模拟赛 2
    胡测7我怎么这么菜!我怎么这么菜!我怎么这么菜!T1命题从内到外考虑,设\(f(i,s1,s2)\)为当前位置\(i\),\([i+1,n]\)部分\(x\)取值为\(s2\),\([1,i]\)部分每个位置上是全称量词或存在量词取值为\(s1\)的情况下命题是否成立,这样DP时从\(i-1\)到\(i\)的转移就是第\(i......
  • 2023.4.20每日总结
    政策查询javapackagewangzhan;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;publicclassThesql{publicConnectionconnect;publicThesql()throwsException{Cla......
  • android折线图的实现
    一:配置参考上篇博客二:模板代码MainActivity:publicclassMainActivityextendsAppCompatActivity{privateLineChartmChart;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentVi......
  • 4.20每日总结
    <%@pageimport="wangzhan.Pd_zhengce"%><%@pageimport="wangzhan.Thesql"%><%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtm......