Android进程使用Messenger通信

作者: SpikeKing | 来源:发表于2016-05-17 17:46 被阅读611次

    欢迎Follow我的GitHub, 关注我的简书. 其余参考Android目录.

    Messenger

    本文的合集已经编著成书,高级Android开发强化实战,欢迎各位读友的建议和指导。在京东即可购买:https://item.jd.com/12385680.html

    Android

    进程之间不能共享内存数据, 但是可以进行通信, 除了简单的Intent通信, 也可以使用Messenger, Messenger基于AIDL实现, 顺序执行, 不支持并发. 为了区分通信的始末, 我们暂定发送数据是客户端, 接收数据是服务端. 本文介绍Messenger的使用方式, 含有Demo.

    本文源码的GitHub下载地址


    客户端

    客户端发送数据到服务端, 服务端收到数据反馈回客户端.

    接收反馈数据

    MainActivity作为客户端, 发送信息. 首先创建消息的Handler类, 用于接收服务端的反馈, 继承Handler, 重写handleMessage方法, msg.what类型, msg.getData()数据.

    private static class MessengerHandler extends Handler {
        private Context mContext;
    
        public MessengerHandler(Context context) {
            mContext = context.getApplicationContext();
        }
    
        @Override public void handleMessage(Message msg) {
            switch (msg.what) {
                case ParasConsts.MSG_FROM_SERVICE:
                    String content = String.valueOf("客户端 - 收到信息: " + msg.getData().getString(ParasConsts.REPLY_ARG));
                    Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }
    

    使用Handler创建Messenger.

    mReplyMessenger = new Messenger(new MessengerHandler(getApplicationContext()));
    // ...
    msg.replyTo = mReplyMessenger;
    

    连接服务发送数据

    创建ServiceConnection类, 实现onServiceConnected方法. 创建信使Messenger, 创建消息Message, 在Message中添加序列化数据msg.setData(), 设置接收反馈msg.replyTo. Messenger发送数据send.

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override public void onServiceConnected(ComponentName name, IBinder service) {
            mMessenger = new Messenger(service);
            Message msg = Message.obtain(null, ParasConsts.MSG_FROM_CLIENT);
            Bundle data = new Bundle();
            data.putString(ParasConsts.MSG_ARG, "Hello, I'm Spike, your friends.");
            msg.setData(data);
    
            // 需要设置Reply的Messenger.
            msg.replyTo = mReplyMessenger;
    
            try {
                mMessenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    
        @Override public void onServiceDisconnected(ComponentName name) {
    
        }
    };
    

    注意信使: Messenger, 消息: Message, 拼写略有不同.

    绑定服务

    添加Connection, 使用Context.BIND_AUTO_CREATE, 绑定自动创建.

    public void bindService(View view) {
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }
    

    解绑服务unbindService.

    public void unbindService(View view) {
        try {
            unbindService(mConnection);
            Toast.makeText(view.getContext(), "解绑成功", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(view.getContext(), "未绑定", Toast.LENGTH_SHORT).show();
        }
    }
    

    绑定服务一定需要解绑服务, 防止泄露. 如果没有注册, 解绑会发生异常.


    服务端

    服务端负责接收数据, 收到给客户端反馈.

    MessengerService继承Service, 显示客户端消息msg.getData(). 反馈信息的Messenger使用客户端传递的, 创建消息添加内容, 使用客户端的Messenger传递给客户端.

    处理与反馈数据

    /**
     * 信使的持有, 处理返回信息
     */
    private static class MessengerHandler extends Handler {
        private Context mContext;
    
        public MessengerHandler(Context context) {
            mContext = context.getApplicationContext();
        }
    
        @Override public void handleMessage(Message msg) {
            switch (msg.what) {
                case ParasConsts.MSG_FROM_CLIENT:
    
                    // 收到消息
                    String content = String.valueOf("服务端 - 收到消息: "
                            + msg.getData().getString(ParasConsts.MSG_ARG));
                    Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show();
    
                    // 回复消息
                    Messenger client = msg.replyTo;
                    Message reply = Message.obtain(null, ParasConsts.MSG_FROM_SERVICE);
                    Bundle data = new Bundle();
                    data.putString(ParasConsts.REPLY_ARG, "消息已经收到");
                    reply.setData(data);
    
                    // 发生Reply的信息
                    try {
                        client.send(reply);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
    
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }
    

    绑定接收数据

    使用Handler创建服务端的Messenger

    mMessenger = new Messenger(new MessengerHandler(getApplicationContext()));
    

    绑定Handler, 与客户端交流.

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

    默认返回null.


    客户端, 使用Messenger传递消息Message, Message中添加序列化数据Bundle; 服务端, 使用Handler解析获取的Message, 通过辨别类型, 获取数据. Messenger使用非常明晰, 易于控制, 是简单进程通信的首选.

    OK, that's all! Enjoy it!

    相关文章

      网友评论

        本文标题:Android进程使用Messenger通信

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