Messenger
Messenger翻譯為信使,即它可以在不同進程中傳遞Message對象。在Message中放入我們需要傳遞的數(shù)據(jù),就可以輕松地實現(xiàn)地實現(xiàn)數(shù)據(jù)的數(shù)據(jù)間傳遞了。它的底層實現(xiàn)是AIDL。從構(gòu)造函數(shù)可以明顯看到AILD的痕跡钧嘶,不管是IMessenger還是Stub.asInterface這種使用方法都是表面它的底層的AIDL。
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
使用Messenger進行跨進程通信
- 服務(wù)端進程
需要在服務(wù)端創(chuàng)建一個Service來處理客戶端的連接請求琳疏,同時創(chuàng)建一個Handler并通過它來創(chuàng)建一個Messenger對象有决,然后在Service的onBind中返回這個Messenger對象底層的Binder即可。 - 客戶端進程中空盼,首先要綁定服務(wù)端的Service,綁定成功后用服務(wù)端返回的IBinder對象創(chuàng)建一個Messenger,通過這個Messenger就可以向服務(wù)端發(fā)送消息了书幕。發(fā)送消息類型是Messeage對象。如果需要服務(wù)端能夠回應(yīng)客戶端揽趾,就和服務(wù)端一樣台汇,我們還需要創(chuàng)建一個Handler并創(chuàng)建一個新的Messenger,并把這個Messenger對象通過Message的replyTo參數(shù)傳遞給服務(wù)器,服務(wù)器通過這個replyTo參數(shù)就可以回應(yīng)客戶端篱瞎。
服務(wù)端的代碼
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_CLIENT:
Log.i(TAG, "來自客戶端的消息" + msg.getData().getString("msg"));
Messenger client = msg.replyTo;
Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("reply", "嗯苟呐,你的消息我已經(jīng)收到,稍后會回復(fù)你俐筋。");
relpyMessage.setData(bundle);
try {
client.send(relpyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}
解析:可以看到MessengerHandler 是用來處理客戶端發(fā)送過來的消息牵素,mMessenger 是一個Messenger對象,它和MessengerHandler相關(guān)聯(lián)校哎,并在onBind方法中返回它里面的Binder對象两波,可以看出,這里的Messenger的作用是將客戶端發(fā)送的消息傳遞給MessengerHandler處理闷哆。注意,注冊service单起,讓其運行在單獨的進程中:
<service
android:name=".Messenger.MessengerService"
android:process=":remote"
android:exported="true">
<intent-filter>
<action android:name="com.lu.ipc.remote" />
</intent-filter>
</service>
客戶端的代碼
在onCreate()中綁定遠程進程的MessengerService抱怔。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent("com.lu.ipc.remote");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
intent=createExplicitFromImplicitIntent(this,intent);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
綁定成功后根據(jù)服務(wù)端返回的binder對象創(chuàng)建Messenger對象并使用此對象向服務(wù)端發(fā)送消息,代碼中創(chuàng)建的Bundle包括了文本消息和客戶端的Messenger對象嘀倒,此對象可以是接收來自服務(wù)端的消息屈留。
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mService = new Messenger(service);
Log.d(TAG, "bind service");
Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg", "從服務(wù)端發(fā)送消息");
msg.setData(data);
msg.replyTo = mGetReplyMessenger;
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
}
};
接收來自服務(wù)端的消息
private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_SERVICE:
Log.i(TAG, "接收到來自服務(wù)端的消息:" + msg.getData().getString("reply"));
break;
default:
super.handleMessage(msg);
}
}
}
總結(jié)
上面的例子是個很經(jīng)典的使用Messenger進行跨進程通信的例子,所以是在同一個應(yīng)用中测蘑,但是服務(wù)端是在不同的進程的灌危,這個和分別在兩個不同的應(yīng)用道理是一樣的,有興趣可以自己試試碳胳。在Messenger中進行數(shù)據(jù)傳遞必須將數(shù)據(jù)放入Message中勇蝙,而Messenger和Message都實現(xiàn)了Parcelable接口,因此可以進行跨進程的通信挨约。