Android进程使用Messenger通信
進(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.
Messenger
本文源碼的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();} 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() { 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();}} 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();} 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, 與客戶端交流.
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!
原文地址:?http://www.jianshu.com/p/56ce3d9fc00d總結(jié)
以上是生活随笔為你收集整理的Android进程使用Messenger通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实现AIDL接口的Binder连接池
- 下一篇: 关于intent-filter的误区