参考https://www.sohu.com/a/314677281_216613
并补充
1、使用Bundle的方式
在Android中三大组件(Activity,Service,Receiver)都支持在Intent中传递Bundle数据,由于Bundle实现了Parcelable接口(一种特有的序列化方法),所以它可以很方便的在不同的进程之间进行传输。当在一个进程中启动另外一个进程的Activity,Service,Receiver时,可以在Bundle中附加需要传输给远程的进程的信息,并通过Intent发送出去。
putExtras(Bundle data):向Intent中放入所需要“携带”的数据包。
Bundle getExtras():取出Intent中所“携带”的数据包。
2、使用文件共享的方式
文件共享:将对象序列化之后保存到文件中,在通过反序列,将对象从文件中读取出来。此方式对文件的格式没有具体的要求,可以是文件、XML、JSON等。
文件共享方式也存在着很大的局限性,如并发读/写问题,如读取的数据不完整或者读取的数据不是最新的。文件共享适合在对数据同步要求不高的进程间通信,并且要妥善处理并发读/写的问题。
3、使用Messenger的方式
我们也可以通过Messenger来进行进程间通信,在Messenger中放入我们需要传递的数据,实现进程间数据传递。Messenger只能传递Message对象,Messenger是一种轻量级的IPC方案,它的底层实现是AIDL。
服务端
(1):创建Service;
(2):构造Handler对象,实现handlerMessage方法;
(3):通过Handler对象,构造Messenger对象;
(4):通过Service的onBind()返回这个Messenger对象底层的Binder对象;
客户端
(1):创建Actvity;
(2):绑定远程进程Service;
(3):创建ServiceConnection,监听绑定服务的回调;
(4):通过onServiceConnected()方法的参数,构造客户端Messenger对象;
(5):通过Messenger向服务端发送消息。
4、使用AIDL的方式
AIDL(Android Interface Definition Language)是一种IDL语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。
如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。AIDL是IPC的一个轻量级实现,Android也提供了一个工具,可以自动创建Stub(类架构,类骨架)。在应用间通信时,需要以下几步:
(1):定义一个AIDL接口;
(2):为远程服务(Service)实现对应Stub;
(3):将服务“暴露”给客户程序使用;
只有当你允许来自不同的客户端访问你的服务并且需要处理多线程问题时你才必须使用AIDL,其他情况下都可以选择其他方法。AIDL是处理多线程、多客户端并发访问的,而Messenger是单线程处理。
5. 第三方库HermesEventBus
贴自作者的github说明
HermesEventBus
HermesEventBus是一个基于EventBus的、能在进程间发送和接收event的库,在IPC或者插件开发中非常有用。它底层基于EventBus,并且和EventBus有相同API。
EventBus是Android系统上使用最广泛的简化模块之间通信的库。但它不支持进程间收发事件。
所以,我开发了HermesEventBus来支持进程间事件收发。
注意:本库基于EventBus 3.0.0。如果你之前使用的是老版本,那么必须修改你的代码,否则将无法接收event。但是修改比较简单。
之前使用“onEventXXX”名字的方法要加上注解,并且在后面附上线程模式:
@Subscribe(threadMode = ThreadMode.MAIN)
public void showText(String text) {
textView.setText(text);
}
原理
事件收发是基于EventBus,IPC通信是基于Hermes。Hermes是一个简单易用的Android IPC库。
本库首先选一个进程作为主进程,将其他进程作为子进程。
每次一个event被发送都会经过以下四步:
1)使用Hermes库将event传递给主进程。
2)主进程使用EventBus在主进程内部发送event。
3)主进程使用Hermes库将event传递给所有的子进程。
4)每个子进程使用EventBus在子进程内部发送event。