Android Messenger跨程序通訊
1、目的
實現不同程序間的通訊。可以將客戶端的資料通過Message傳遞到服務端,同時服務端的資料也可以通過Message返回到客戶端。
2、原理
不同程序間的通訊通過Messenger為服務端建立介面,客戶端就可以Message傳送給服務端,交給服務端的Handler進行處理訊息;當然客戶端也可以定義Messenger,方便服務端將處理完的訊息返回給客戶端。
在單一執行緒中建立包含所有請求的佇列,採用序列的方式來處理客戶端傳送來的訊息。
侷限性:不能處理大量併發請求。因為所有的請求都是序列執行
3、使用過程
(1)客戶端傳送message到服務端
建立一個類繼承於Service
(a)伺服器實現一個Handler,來接收客戶端的訊息
private class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
Log.d("MessService","Message is from client");
}
}
(b)通過上面建立的Handler來建立Messenger物件
private Messenger messenger = new Messenger(new MessengerHandler());
(c)將上述的Messenger建立IBinder,通過onBinder返回給客戶端
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
在Acitivity中實現bind該service
(e)客戶端bind該service
private ServiceConnection messConnect = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { isBinderService = true; servermessenger = new Messenger(service); Log.d("MessService","bind success"); Message msg = Message.obtain(); msg.what = 1; msg.arg1 = 2; try { servermessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { isBinderService = false; servermessenger = null; } }; private void startMessService(){ if (isBinderService){ return; } isBinderService= bindService(new Intent(MainActivity.this, MessService.class),messConnect,Context.BIND_AUTO_CREATE); }
(f)在AndroidMenifest檔案中註冊該服務,這裡將該Service放到另外一個程序中
<service android:name=".service.MessService"
android:process=".messservice">
</service>
上述幾步就可以實現了將Message傳送到服務端,列印日誌如下:
10-30 14:30:57.261 6094-6094/com.j1 D/MessService: bind success
10-30 14:30:57.262 6137-6137/? D/MessService: Message is from client
(2)服務端回撥message到客戶端
在Activity中
(a)在客戶端中定義自己的Messenger
private Messenger clientMessenger = new Messenger(new Handler(){
@Override
public void handleMessage(Message msg) {
Log.d("MessService","get msg from server"+msg.what+", "+msg.arg1);
}
});
(b)將該定義的Messenger和傳送給服務端的Message繫結到一起,可以在服務端接收到Message的時候,獲得該Messenger,方便伺服器回傳Message。
在上面的(e)中建立的Message中繫結該Messenger
//。。。。省略程式碼
Message msg = Message.obtain();
msg.what = 1;
msg.arg1 = 2;
msg.replyTo = clientMessenger;
//。。。。省略程式碼
在自定義的Service中
(c)在服務端需要返回Message的地方獲取(a)建立的Messenger來回傳訊息。我們暫時先放到Handler
@Override
public void handleMessage(Message msg) {
//。。。。省略程式碼
Messenger clientMessenger = msg.replyTo;
try {
clientMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
//。。。。省略程式碼
}
上述幾步就可以完成,服務端將Message返回給客戶端,列印日誌如下:
10-30 15:16:12.290 7944-7944/com.j1 D/MessService: get msg from server
4、總結
(1)Messenger對AIDL進行封裝,可以實現基於訊息的跨程序通訊。
(2)客戶端和服務端都可以Messenger來傳遞訊息,通過msg.repayTo = clientMessenger來將客戶端的Messenger傳遞給服務端。
(3)