Android進(jìn)程使用Messenger通信

歡迎Follow我的GitHub, 關(guān)注我的簡書. 其余參考Android目錄.

Messenger

本文的合集已經(jīng)編著成書,高級Android開發(fā)強(qiáng)化實戰(zhàn),歡迎各位讀友的建議和指導(dǎo)。在京東即可購買:https://item.jd.com/12385680.html

Android

進(jìn)程之間不能共享內(nèi)存數(shù)據(jù), 但是可以進(jìn)行通信, 除了簡單的Intent通信, 也可以使用Messenger, Messenger基于AIDL實現(xiàn), 順序執(zhí)行, 不支持并發(fā). 為了區(qū)分通信的始末, 我們暫定發(fā)送數(shù)據(jù)是客戶端, 接收數(shù)據(jù)是服務(wù)端. 本文介紹Messenger的使用方式, 含有Demo.

本文源碼的GitHub下載地址


客戶端

客戶端發(fā)送數(shù)據(jù)到服務(wù)端, 服務(wù)端收到數(shù)據(jù)反饋回客戶端.

接收反饋數(shù)據(jù)

MainActivity作為客戶端, 發(fā)送信息. 首先創(chuàng)建消息的Handler類, 用于接收服務(wù)端的反饋, 繼承Handler, 重寫handleMessage方法, msg.what類型, msg.getData()數(shù)據(jù).

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創(chuàng)建Messenger.

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

連接服務(wù)發(fā)送數(shù)據(jù)

創(chuàng)建ServiceConnection類, 實現(xiàn)onServiceConnected方法. 創(chuàng)建信使Messenger, 創(chuàng)建消息Message, 在Message中添加序列化數(shù)據(jù)msg.setData(), 設(shè)置接收反饋msg.replyTo. Messenger發(fā)送數(shù)據(jù)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);

        // 需要設(shè)置Reply的Messenger.
        msg.replyTo = mReplyMessenger;

        try {
            mMessenger.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override public void onServiceDisconnected(ComponentName name) {

    }
};

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

綁定服務(wù)

添加Connection, 使用Context.BIND_AUTO_CREATE, 綁定自動創(chuàng)建.

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

解綁服務(wù)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();
    }
}

綁定服務(wù)一定需要解綁服務(wù), 防止泄露. 如果沒有注冊, 解綁會發(fā)生異常.


服務(wù)端

服務(wù)端負(fù)責(zé)接收數(shù)據(jù), 收到給客戶端反饋.

MessengerService繼承Service, 顯示客戶端消息msg.getData(). 反饋信息的Messenger使用客戶端傳遞的, 創(chuàng)建消息添加內(nèi)容, 使用客戶端的Messenger傳遞給客戶端.

處理與反饋數(shù)據(jù)

/**
 * 信使的持有, 處理返回信息
 */
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("服務(wù)端 - 收到消息: "
                        + msg.getData().getString(ParasConsts.MSG_ARG));
                Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show();

                // 回復(fù)消息
                Messenger client = msg.replyTo;
                Message reply = Message.obtain(null, ParasConsts.MSG_FROM_SERVICE);
                Bundle data = new Bundle();
                data.putString(ParasConsts.REPLY_ARG, "消息已經(jīng)收到");
                reply.setData(data);

                // 發(fā)生Reply的信息
                try {
                    client.send(reply);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

                break;
            default:
                super.handleMessage(msg);
        }
    }
}

綁定接收數(shù)據(jù)

使用Handler創(chuàng)建服務(wù)端的Messenger

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

綁定Handler, 與客戶端交流.

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

默認(rèn)返回null.


客戶端, 使用Messenger傳遞消息Message, Message中添加序列化數(shù)據(jù)Bundle; 服務(wù)端, 使用Handler解析獲取的Message, 通過辨別類型, 獲取數(shù)據(jù). Messenger使用非常明晰, 易于控制, 是簡單進(jìn)程通信的首選.

OK, that's all! Enjoy it!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android跨進(jìn)程通信IPC整體內(nèi)容如下 1、Android跨進(jìn)程通信IPC之1——Linux基礎(chǔ)2、Andro...
    隔壁老李頭閱讀 3,947評論 3 12
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 轉(zhuǎn)載請注明出處:http://www.itdecent.cn/p/e6867aa8f267[https://www...
    朋永閱讀 1,959評論 0 2
  • 今天是二零一六年一月二十三日。這還是第十九篇簡書。 ...劃等號,所以問我冷不冷,我通常是不冷的,問我無聊不無聊,...
    塵___世_美閱讀 203評論 0 0
  • 2016年12月24日下午2點到5點,全國碩士研究生統(tǒng)考英語。今年作文是根據(jù)兩幅圖上的內(nèi)容,寫一篇兩百字左右...
    學(xué)者茶館閱讀 14,387評論 2 9

友情鏈接更多精彩內(nèi)容