歡迎Follow我的GitHub: https://github.com/SpikeKing
本文的合集已經編著成書,高級Android開發強化實戰,歡迎各位讀友的建議和指導。在京東即可購買:https://item.jd.com/12385680.html
進程之間不能共享內存數據, 但是可以進行通信, 除了簡單的Intent通信, 也可以使用Messenger, Messenger基於AIDL實現, 順序執行, 不支持併發. 爲了區分通信的始末, 我們暫定發送數據是客戶端, 接收數據是服務端. 本文介紹Messenger的使用方式, 含有Demo.
本文源碼的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, 掘金.
我已委託“維權騎士”爲我的文章進行維權行動. 未經授權, 禁止轉載, 授權或合作請留言.