进程间通信之messenger

  • Post author:
  • Post category:其他


使用messenger完成进程间通信


messenger可以翻译为信使,故名思议他可以在进程间传递message,我们可以将数据封装在message中通过messenger在进程间完成传递,messenger是一种轻量级的IPC(进程间通信,跨进程通信)方案,是AIDL的上层封装



好处:

使用简单,方便调用,不存在并发,因为他是串行方式处理客户端数据


弊端:

串行方式处理客户端数据,一次只会处理一个请求,如果有大量的并发请求,他也只会一个一个处理,基本只能用于传递消息,无法通过跨进程调用服务端的方法


用处:

一般用于传递消息



使用:

分为服务端和客户端来使用,下面使用Demo说明


1.服务端


首先我们创建一个service,用于连接客户端,并创建一个handler和Messenger关联,并在onBind方法中返回这个Messenger的底层iBinder即可,这里Messenger的作用就是将客户端的数据交给handler来处理,注意服务端是要运行在独立的进程中,也就是服务的service要声明process属性,这样等同于模仿两个应用,完成跨进程通信


2.客户端


客户端需要绑定服务端的service,通过绑定成功后的iBinder对象创建messenger,通过这个messenger就可以向服务端发送数据了,如果需要服务端返回数据给客户端,那么就需要在客户端也创建一个Handler和messenger关联 并且将这个messenger通过message的replyTo参数传递给服务端,服务端通过这个replyTo参数就可以拿到客户端的messenger了就可以返回数据了,下面看下代码一目“鸟”然


服务端代码:

/*ipc之messenger通信 服务端 运行在独立进程中*/
public class MessengerService extends Service {

    private static final String TAG = "MessengerService";

    private static class messengerHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.MSG_FROM_CLIENT:
                    Log.d(TAG, "handleMessage : " + msg.getData().getString("msg"));
                    //replyTo获取的是客户端message设置的messenger,这个messenger和客户端的handler关联了 所以客户端是可以收到服务端返回的消息
                    Messenger client = msg.replyTo;
                    //messenger只能发送message 当然他们都实现了Parcelable 所以可以在进程间传递
                    Message replyMessage = Message.obtain(null, Constants.MSG_FROM_SERVICE);
                    //bundle可以存放比较多的数据类型且实现了Parcelable message的object非系统的Parcelable无法通过Object来传输,所以实用性比较低
                    Bundle data = new Bundle();
                    data.putString("msg", "黄河黄河我是长江");
                    replyMessage.setData(data);
                    try {
                        client.send(replyMessage);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }

    //将mseeengerHandler和Messenger关联起来 这样就可以收到mMessenger发送过来的数据
    private final Messenger mMessenger = new Messenger(new messengerHandler());

    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
}

服务端的service需要运行在独立的进程中,所以我们在清单中声明一下android:process=”:remote”



客户端代码

/*ipc之messenger通信 客户端*/
public class MessengerActivity extends AppCompatActivity {

    private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());

    private static class MessengerHandler extends Handler {

        private static final String TAG = "MessengerService";

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.MSG_FROM_SERVICE:
                    Log.d(TAG, "handleMessage : " + msg.getData().getString("msg"));
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = new Messenger(service);
            Message msg = Message.obtain(null, Constants.MSG_FROM_CLIENT);
            Bundle data = new Bundle();
            data.putString("msg", "长江长江我是黄河");
            msg.setData(data);
            //如果不把mGetReplyMessenger赋值给replyTo 那么服务端就会获取空的messenger  也就无法返回数据
            msg.replyTo = mGetReplyMessenger;
            try {
                mService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    private Messenger mService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);
        //绑定服务端的service
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mConnection);
    }
}


最后看下客户端和服务端的交互log

08-22 09:17:01.797 4219-4219/? D/MessengerService: handleMessage : 长江长江我是黄河
08-22 09:17:01.897 4206-4206/? D/MessengerService: handleMessage : 黄河黄河我是长江



版权声明:本文为duo_shine原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。