「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...