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, 掘金.
我已委託“維權騎士”爲我的文章進行維權行動. 未經授權, 禁止轉載, 授權或合作請留言.

發佈了721 篇原創文章 · 獲贊 3023 · 訪問量 409萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章