美文网首页
Android跨进程通信IPC之22--Messenger

Android跨进程通信IPC之22--Messenger

作者: 凯玲之恋 | 来源:发表于2018-08-31 10:53 被阅读11次

    移步系列Android跨进程通信IPC系列

    1 概述

    • Messenger是一种轻量级的IPC方案,其底层实现原理就是AIDL,它对AIDL做了一次封装,所以使用方法会比AIDL简单,由于它的效率比较低一次只能处理一次请求,所以不存在线程同步的问题
      5713484-338c2db71a490dfc.png

    2 示例(通过Messenger实现客户端与服务端跨进程通信)

    2.1 服务端

    在其他进程

    public class MessagerService extends Service {
    
        private Messenger messenger = new Messenger(new MessaengerHandler());
    
        private static class MessaengerHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case Constants.CLENT_MESSAGE:
                        Log.i("GELAOLITOU", "收到消息:" + msg.getData().get(Constants.KEY));
                        //客户端Messenger 
                        Messenger msgr_client = msg.replyTo;
                        Message mes_reply = Message.obtain(null, Constants.SERVER_MESSAGE);
                        Bundle bundle = new Bundle();
                        bundle.putString(Constants.REPLY_KEY, "你的信息我已经收到,现在就回复你");
                        mes_reply.setData(bundle);
    
                        try {
                            msgr_client.send(mes_reply);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return messenger.getBinder();
        }
    
    
    }
    

    2.2 客户端

    public class MessagerClientActivity extends BaseActivity {
    
    
        public static void show(Activity activity) {
            Intent intent = new Intent(activity, MessagerClientActivity.class);
            activity.startActivity(intent);
        }
    
        private Messenger serverMessager;
    
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                //获取服务端messager
                serverMessager = new Messenger(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
        //创建客户端messager
        private Messenger mGetReplyMessenger = new Messenger(new MessengerClientHandler(this));
        //客户端消息处理
        private static class MessengerClientHandler extends Handler {
    
            private WeakReference<MessagerClientActivity> messagerClientActivityWeakReference;
    
            private MessengerClientHandler(MessagerClientActivity messagerClientActivity) {
                messagerClientActivityWeakReference = new WeakReference<MessagerClientActivity>(messagerClientActivity);
            }
    
            @Override
            public void handleMessage(Message msg) {
    
    
                switch (msg.what) {
                    case Constants.SERVER_MESSAGE:
                        MessagerClientActivity activity = messagerClientActivityWeakReference.get();
                        if (activity != null) {
                            activity.handleMessage(msg);
                        }
                        break;
                }
    
            }
    
        }
    
        private void handleMessage(Message msg) {
            content.setText("收到 服务端的消息,消息内容是" + msg.getData().getString(Constants.REPLY_KEY));
        }
    
        private TextView content;
    
        @Override
        protected int getLayoutResId() {
            return R.layout.activity_messager_client;
        }
    
        @Override
        protected void initView() {
    
            findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //向服务端发送消息
                    sendMessage();
                }
            });
            content = findViewById(R.id.content);
        }
    
        @Override
        protected void initData() {
            super.initData();
            Intent intent = new Intent(this, MessagerService.class);
            bindService(intent, connection, Context.BIND_AUTO_CREATE);
        }
    
        @Override
        protected void onDestroy() {
            unbindService(connection);
            super.onDestroy();
        }
    
        private void sendMessage() {
            if (serverMessager == null) {
                return;
            }
    
            //创建一个what值为Constants.CLENT_MESSAGE的message
            Message message = Message.obtain(null, Constants.CLENT_MESSAGE);
            Bundle bundle = new Bundle();
            bundle.putString(Constants.KEY, "我是来自客户端的信息");
            message.setData(bundle);
    
            //将客户端Messenger传递给服务端
            message.replyTo = mGetReplyMessenger;
            try {
                serverMessager.send(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    3 源码分析

    public final class Messenger implements Parcelable {}
    

    3.1 类结构

    TIM截图20180831093732.png

    3.2 构造方法

        private final IMessenger mTarget;
        public Messenger(Handler target) {
            mTarget = target.getIMessenger();
        }
    
        public Messenger(IBinder target) {
            mTarget = IMessenger.Stub.asInterface(target);
        }
    
      1. 参数是Handler
      • 传入一个Handler作为参数创建一个新的Messenger
      • 通过该Messenger发送的任何消息对象将会出现在这个Handler里面,就像Handler直接调用sendMessage(Message)一样。入参target接收这些已经发送的消息。
      1. 参数是IBinder
      • 根据原始的IBinder来创建一个Messenger对象,可以通过getBinder()方法来获取这个IBinder对象。入参target其实就是这个Messenger与之通信的
        *其中IMessenger.Stub.asInterface(target);这个方法简直就是AIDL方式

    3.2.1 getIMessenger()

    [Handler.java]

        IMessenger mMessenger;
        final IMessenger getIMessenger() {
            synchronized (mQueue) {
                if (mMessenger != null) {
                    return mMessenger;
                }
                mMessenger = new MessengerImpl();
                return mMessenger;
            }
        }
        private final class MessengerImpl extends IMessenger.Stub {
            public void send(Message msg) {
                msg.sendingUid = Binder.getCallingUid();
                Handler.this.sendMessage(msg);
            }
        }
    
      1. IMessenger,Stub --->IMessenger.aidl--Messenger底层是基于AIDL的
      1. 当发送消息的时候,调用是Handler.this.sendMessage(msg);,其实就是自己调用的sendMessage(msg)方法而已。

    3.2.2 IMessenger.Stub.asInterface(target)

    Android跨进程通信IPC之19——AIDL
    返回一个封装过的Stub.Proxy,也是一个代理类

    3.3 其他两个重要方法

    3.3.1 Messenger.getBinder()方法

        public IBinder getBinder() {
            return mTarget.asBinder();
        }
    

    mTarget.asBinder()等价于代理类Stub.Proxy.asBinder()
    请看Android跨进程通信IPC之19——AIDL
    asBinder()中返回--

    3.3.2 send(Message msg)方法

        public void send(Message message) throws RemoteException {
            mTarget.send(message);
        }
    

    发送一个message对象到 messagerHandler。这里我们传递的参数是一个Message对象

    上面内容 未完待续

    参考

    Android跨进程通信IPC之14——其他IPC方式

    相关文章

      网友评论

          本文标题:Android跨进程通信IPC之22--Messenger

          本文链接:https://www.haomeiwen.com/subject/wdhjwftx.html