「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端:

  1. Server端
    需要在Server端创建一个Service来处理Client端的连接请求,同时创建一个Handler对象并通过它来创建一个Messenger对象,然后在Service的onBind中()方法返回这个Messenger对象底层的Binder。
  2. 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...

更多相关文章

  1. Android(安卓)AIDL demo
  2. Android下载文本文件和mp3文件
  3. Android(安卓)获取imei号码,获取手机型号和系统版本号等信息
  4. android 获取手机的信息
  5. android > 调用拨打电话 并子线程监控然后返回跳转
  6. android音频架构
  7. Android的内存泄漏和调试
  8. Android实现Bitmap高斯模糊效果
  9. Android之Handler用法总结

随机推荐

  1. Android系统服务-简介
  2. 13-5-16 Android自定义空间实现wifi信号
  3. android 单元测试
  4. 关于android分辨率兼容问题(一)
  5. Android(安卓)Studio 安装、设置、快捷键
  6. Android实现截图分享qq 微信功能
  7. Android的Window类
  8. 针对安卓软硬件碎片化,谷歌为何不作为?(转)
  9. 如何选好Android开发书籍和教程[总结]
  10. Android事件分发机制源码分析之View篇