「Android」基于轻量级Messenger的进程通信
Android中目前存在多种IPC方式,分别为:
- Bundle
- 文件共享
- Messenger
- AIDL
- ContentProvider
- Socket
Messenger
Messenger是一种轻量级的IPC方案,它的底层实现是基于AIDL:
/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
Messenger对AIDL做了封装,使得我们可以更简便的进行进程通信。同时,它一次处理一个请求,不存在并发执行的情形,因此在服务端不需要考虑线程同步问题。
Messenger原理图
实现一个Messenger主要分为Server端和Client端:
- Server端
需要在Server端创建一个Service来处理Client端的连接请求,同时创建一个Handler对象并通过它来创建一个Messenger对象,然后在Service的onBind中()方法返回这个Messenger对象底层的Binder。 - Client端
首先需要绑定Server端的Service,绑定成功后即可获取到Server端返回的IBinder对象并通过它创建一个Messenger对象,通过这个Messenger对象就可以向Server端发送消息,发消息的类型为Message对象。
如果需要Server端回应Client端,如同Server端一样,Client端也需要创建一个Handler对象并通过它来创建一个Messenger对象,并把这个Messenger对象通过Message的replyTo参数传递给Server端。
Server端可通过这个replyTo参数获取到Client端的Messenger对象,并通过这个Messenger对象就可以向Client端发送消息
Server端示例代码
public class MessengerService extends Service {
private static class ServerMessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_FROM_CLIENT:
// 通过Message,获取Client端的Messenger对象
mClientMessenger = msg.replyTo;
Message replyMessage = Message.obtain(null, MSG_FROM_SERVER);
Bundle bundle = new Bundle();
// 将data,添加进Message
bundle.putString(DATA, DATA);
replyMessage.setData(bundle);
try {
// 向Client端发送Message
mClientMessenger.send(replyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
private final Messenger mServerMessenger = new Messenger(new ServerMessengerHandler());
private Messenger mClientMessenger;
@Override
public IBinder onBind(Intent intent) {
return mServerMessenger.getBinder();
}
}
Client端示例代码
public class MessengerClient extends Context{
private static class ClientMessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_FROM_SERVER:
// 获取data
String data = msg.getData().getString(DATA);
break;
}
}
}
private boolean mBound;
private final Messenger mClientMessenger = new Messenger(new ClientMessengerHandler());
private Messenger mServerMessenger;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 通过IBinder对象,获取Server端的Messenger对象
mServerMessenger = new Messenger(service);
mBound = true;
Message requestMessage = Message.obtain(null, MSG_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString(REQUEST, REQUEST);
requestMessage.setData(bundle);
// 将Client端的Messenger对象,添加进Message
mClientMessenger = new Messenger(mHandler);
requestMessage.replyTo = mClientMessenger;
try {
// 向Server端发送Message
mServerMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mServerMessenger = null;
mBound = false;
}
}
// 请求data
// Client端触发基于Messenger的IPC流程
private void doBindService() {
Intent intent = new Intent(this, MessengerServer.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
}
IPC方式的优缺点和适用场景
方式 | 能力 | 特点 | 适用场景 |
---|---|---|---|
AIDL | 支持一对多并发通信、支持实时通信、支持跨进程函数调用 | 需要独立定义.aidl规范、需要添加.aidl文件、使用较复杂 | 一对多即时通信,有RPC需求 |
Messenger | 支持一对多串行通信、支持实时通信、支持Bundle传递 | 无需独立定义.aidl规范、无需添加.aidl文件、使用较简洁 | 低并发的一对多即时通信,无返回结果的RPC需求 |
参考
https://developer.android.goo...
https://developer.android.goo...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。