Android进程使用Messenger通信

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


Messenger

本文源码的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.jianshu.com/p/56ce3d9fc00d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值