Android之跨进程通信的方式

2,056 阅读5分钟

跨进程通信是android开发中一个非常基础的知识点。这篇文章主要放在跨进程通信中的AIDL和Binder进行讲解。主要还是将自己的理解用WHY-WHAT-HOW的方法写出来,检验自己的学习成果。

1. 为什么需要跨进程通信

Android中大部分项目都使用到了多进程的模式来进行开发,但其实单进程也可以支持app的正常运行。为什么大家都选择了多进程的方式呢?

首先我们先来了解下什么是进程。当一个App运行时,系统会给它分配一个可以资源调度的单位,即进程「Process」。每一个运行中的App,至少会有一个进程。当手机启动了很多App或者在后台运行App时,我们会发现,随着打开的App不断增加,手机会慢慢变卡(当然现在很多手机性能很好,并且App开发者们也很注意App性能,这种情况在高端机型上发生的几率小了很多)。

  • 随着App开启增多,手机变卡,被手动关闭进程。
  • 当App是单进程的时候,退出App后即销毁了,很难再和云端保持通信。
  • 只有一个进程,并且还需要同时处理UI、事务,会使App需要占据很多内存,App会呈现卡顿或者通信不流畅的现象。
  • ……

那么,是否可以让进程各自负责独立事务呢?例如设定UI进程,只负责App启动后处理UI相关的事情,后台进程可以设置为长时间存活的进程,来处理耗时事务或者当UI进程销毁后还可以继续进行事件处理或者联网。在过往经验中,一般会分成三个主要进程。分别为UI进程、后台进程、任务进程。后台进程负责存活,进行小量的后台事务和不定时联网拉取信息。任务进程则主要负责处理占用内存但短时间的任务。做完事情就自我销毁。

进程间是无法共享内存的,所以进行如果需要共享信息或传递信息,就需要IPC通信。 //TODO(这里应该补一张系统级fork进程的图,会更好理解一点。)

2. 什么是跨进程通信

因为多个进程无法进行信息共享,所以需要使用其他方式来进行通信。 Android其实提供了很多中可以解决多进程间通信的方式。

  • Bundle —— Intent间可以使用Bundle来进行基础类型或序列化类型数据的传输
  • 文件共享 —— 多个进程之间使用同一个文件来进行数据交换。但是文件共享需要进行多次IO操作,所有会有并发问题
  • Messager —— 使用Messager来传递Message,但仅限于传递消息,无法进行跨进程的方法调用
  • AIDL —— 本文的重点,AIDL接口可以通过编写AIDL文件由系统生成Binder类,从而来进行跨进程通信。

怎么理解Binder呢?

  • Binder分为Client和Server两个进程,它们是相对的。即谁是发送者,谁就是Client。(可以先这样理解吧)
  • Binder通信的组成以及通信如下图:

IPC即为跨进程通信,而ServiceManager则负责将Server注册到一个容器中。

跨进程通信的过程如下:

  • Server先在SM(ServiceManager)中注册。
  • Client要进行通信,要先获取Server,请求一个Object对象
  • Server并不会直接把真正的对象传给Client,而是返回给一个Proxy对象,即代理对象。
  • 其中,是ServiceManager起到一个代理的作用,帮助Client在Sever中查找到对应的对象并将其通过代理返回给CLient。而Client和Sever实际上并不需要知道内部的过程。
    (其实四大组件的交互原理,也很像Server和Client,而AMS则有点类似SM的作用)

3. 怎么使用跨进程通信

在项目中,其实很少有机会真正接触到AIDl的整个过程。一般都是在别人已经建立好的通信框架上来进行跨进程之间的通信。但不离其宗,基本稳定的跨进程通信都是使用AIDL的方法来处理的。所以这里我也简单放一下进行AIDL的几个步骤。

  • 首先,定义一个aidl接口文件。有两点需要注意的,package 必须和当前路径一致。参数中的inout需要特别注意区别,简单理解为输入输出。
  • 编译后会在package下生成接口的类文件。其中有几个主要方法
    1. Stub类中asInterface方法:主要判断是否在同一进程中,若是,则直接调用方法,若不是,则把IBinder参数包装成Proxy对象,调用Proxy中的方法。
    2. Proxy在自己的方法中,会进行数据类型的判断和逻辑处理,然后将结果通过IBinder的onTransact方法传输给Server端。
    3. Server获取Proxy传输的方法后,经过处理返回给Client。

一次完整的跨进程通信就是这样啦。 此处应该放一个demo例子。 五一后补充吧。代码看起来会更清晰些。

总是觉得自己总结能力和分享能力很差,特别是转化为文字的时候更加不流畅,而我好像更善于在脑子中抽象地理解。希望文章的总结,是帮助自己梳理和更好地理解运用的开始,慢慢加油进步吧。主要是学到之后能够流畅地分享出来呀。这是今年的小心愿和flag。

BTW最近有一件很重要的事情,希望顺利。