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

進(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!