前言
今天把进程间通信的内容复习整理下,算是温故而知新吧。
小结目录
使用Bundle
我们通常在使用
Activity
,Service
,Receiver
的时候,都是支持在Intent中传递Bundle数据的,由于Bundle实现了Parcelable接口,所以它可以通过序列化与反序列化在多个进程之间进行传递数据。
<!--使用bundle方式-->
<activity android:name=".bundle.BundleXActivity" />
<activity android:name=".bundle.BundleYActivity"
android:process=":bundle" />
如图所示
使用文件共享
共享文件说白了,就是多个进程通过读/写
同一个文件来交换数据,但是由于基于Linux系统本身对并发读/写
文件没有限制,因此并发读写容易出问题。例如:
多进程读写SharedPreferences就很容易出现脏数据
。
<!--使用file方式-->
<activity android:name=".file.FileXActivity" />
<activity android:name=".file.FileYActivity"
android:process=":file" />
如图所示
使用Messenger通信
Messenger本身是基于AIDL实现的轻量级的IPC方案。
<!--使用Messenger方式-->
<activity android:name=".messenger.MessengerActivity" />
<service android:name=".messenger.MessengerService"
android:process=":messenger"></service>
定义MessengerService服务端类
public class MessengerService extends Service {
private static final String TAG = MessengerService.class.getSimpleName();
private static class MsgHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MSG_FROM_CLIENT:
ToastUtils.showLong("服务端收到: " + msg.getData().getString("message"));
break;
}
super.handleMessage(msg);
}
}
private final Messenger mMessenger = new Messenger(new MsgHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
在绑定服务成功之后可以使用Messenger发送数据与服务端进行交互:
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
Message msg = Message.obtain(null, Constants.MSG_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("message", "Hello World!");
msg.setData(bundle);
try {
mMessenger.send(msg);
} catch (RemoteException e) {
Log.e(TAG, "Send Message Exception...");
}
}
如图所示
使用AIDL方式
这种方式在实际生产中比较常见,使用AIDL进行进程间的通信其实比较简单:
1. 创建AIDL接口
// IMessage.aidl
package cn.byhook.ipc;
interface IMessage {
String getMessage(int code);
}
然后点击Build/Make Module xxx
- 定义服务端
跟上面的Messenger类似
public class IMessageService extends Service {
private IMessage.Stub messageBinder = new IMessage.Stub() {
@Override
public String getMessage(int code) throws RemoteException {
return "服务端收到: " + code;
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messageBinder;
}
}
- 定义客户端
绑定成功之后即可交互数据
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessage = IMessage.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
这种方式在实际生产过程中很常见
使用ContentProvider方式
ContentProvider
是系统中提供的专门用于不同应用进程间进行数据共享的一种方式,所以在系统中很常见,我们平时读取系统的短信等操作,就会使用到ContentResolver
来进行操作读取。
<!--使用ContentProvider方式-->
<activity android:name=".provider.ProviderActivity" />
<provider
android:name=".provider.MessageProvider"
android:authorities="cn.byhook.ipc.provider"
android:permission="cn.byhook.ipc.permission"
android:process=":provider" />
将Provider和Activity置于不同的进程中,具体代码就不贴了,可以参考下面的例子
小结地址:
https://github.com/byhook/ipc-sample