Android 进程使用 Messenger 通信

欢迎Follow我的GitHub: https://github.com/SpikeKing

Messenger

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

Book

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

更多: http://www.wangchenlong.org/

本文源码的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!


最初发布地址:
http://www.wangchenlong.org/2016/05/17/1605/171-android-messenger/
欢迎Follow我的GitHub, 关注我的简书, CSDN, 掘金.
我已委托“维权骑士”为我的文章进行维权行动. 未经授权, 禁止转载, 授权或合作请留言.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ElminsterAumar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值