本文轉自:http://xwangly.iteye.com/blog/1109424
?
Messenger:信使
官方文檔解釋:它引用了一個Handler對象,以便others能夠向它發送消息(使用mMessenger.send(Message msg)方法)。該類允許跨進程間基于Message的通信(即兩個進程間可以通過Message進行通信),在服務端使用Handler創建一個Messenger,客戶端持有這個Messenger就可以與服務端通信了。
?
以前我們使用Handler+Message的方式進行通信,都是在同一個進程中,從線程持有一個主線程的Handler對象,并向主線程發送消息。
而Android既然可以使用bindler機制進行跨進行通信,所以我們當然可以將Handler與bindler結合起來進行跨進程發送消息。
查看API就可以發現,Messenger就是這種方式的實現。
一般使用方法如下:
1。遠程通過
?
Java代碼 ?
mMessenger?=?new ?Messenger(mHandler)?? ?
mMessenger = new Messenger(mHandler)
?創建一個信使對象
2。客戶端使用bindlerService請求連接遠程
3。遠程onBind方法返回一個bindler
?
Java代碼 ?
return ?mMessenger.getBinder();?? ?
return mMessenger.getBinder();
?4.客戶端使用遠程返回的bindler得到一個信使(即得到遠程信使)
?
Java代碼 ?
????????????public ?void ?onServiceConnected(ComponentName?name,?IBinder?service)?{ ?? ????????????????rMessenger?=?new ?Messenger(service); ?? ...... ?? ????????????}?? ?
public void onServiceConnected(ComponentName name, IBinder service) {rMessenger = new Messenger(service);......}
?這里雖然是new了一個Messenger,但我們查看它的實現
?
Java代碼 ?
? ? ? ? ? ?? public ?Messenger(IBinder?target)?{ ??????mTarget?=?IMessenger.Stub.asInterface(target); ?? }?? ?
/*** Create a Messenger from a raw IBinder, which had previously been* retrieved with {@link #getBinder}.* * @param target The IBinder this Messenger should communicate with.*/public Messenger(IBinder target) {mTarget = IMessenger.Stub.asInterface(target);}
?發現它的mTarget是通過Aidl得到的,實際上就是遠程創建的那個。
5。客戶端可以使用這個遠程信使對象向遠程發送消息:rMessenger.send(msg);
這樣遠程服務端的Handler對象就能收到消息了,然后可以在其handlerMessage(Message msg)方法中進行處理。(該Handler對象就是第一步服務端創建Messenger時使用的參數mHandler).
?
經過這5個步驟貌似只有客戶端向服務端發送消息,這樣的消息傳遞是單向的,那么如何實現雙向傳遞呢?
首先需要在第5步稍加修改,在send(msg)前通過msm.replyTo = mMessenger將自己的信使設置到消息中,這樣服務端接收到消息時同時也得到了客戶端的信使對象了,然后服務端可以通過
?
Java代碼 ?
?? cMessenger?=?msg.replyTo; ?? cMessenger.send(message);?? ?
//得到客戶端的信使對象,并向它發送消息
cMessenger = msg.replyTo;
cMessenger.send(message);
?即完成了從服務端向客戶端發送消息的功能,這樣客服端可以在自己的Handler對象的handlerMessage方法中接收服務端發送來的message進行處理。
雙向通信宣告完成。
?
下面改寫ApiDemos工程實現Messenger通信
MessengerService.java
?
Java代碼 ?
package ?com.xwangly.apidemo.app; ???? import ?java.util.Random; ???? import ?android.app.Service; ??import ?android.content.Intent; ??import ?android.os.Handler; ??import ?android.os.IBinder; ??import ?android.os.Message; ??import ?android.os.Messenger; ??import ?android.os.RemoteException; ??import ?android.util.Log; ???? public ?class ?MessengerService?extends ?Service?{ ??????private ?String?TAG?=?"MessengerService" ; ?? ?? ????@Override ?? ????public ?void ?onDestroy()?{ ?? ?????????? ????????Log.i(TAG,?"onDestroy" ); ?? ????????cMessenger?=?null ; ?? ????????super .onDestroy(); ?? ????} ?? ?? ????@Override ?? ????public ?boolean ?onUnbind(Intent?intent)?{ ?? ?????????? ????????Log.i(TAG,?"onUnbind" ); ?? ????????return ?super .onUnbind(intent); ?? ????} ?? ?? ????static ?final ?int ?MSG_REGISTER_CLIENT?=?1 ; ?? ????static ?final ?int ?MSG_UNREGISTER_CLIENT?=?2 ; ?? ????static ?final ?int ?MSG_SET_VALUE?=?3 ; ?? ?? ????private ?Random?random?=?new ?Random(); ?? ?? ????private ?Handler?mHandler?=?new ?Handler()?{ ?? ?? ????????@Override ?? ????????public ?void ?handleMessage(Message?msg)?{ ?? ?????????????? ????????????Log.i(TAG,?"handleMessage" ); ?? ????????????switch ?(msg.what)?{ ?? ????????????case ?MSG_SET_VALUE: ?? ????????????????try ?{ ?? ????????????????????Message?message?=?Message.obtain(null , ?? ????????????????????????????MessengerService.MSG_SET_VALUE); ?? ????????????????????message.arg1?=?random.nextInt(100 ); ?? ???????????????????? ?? ?????????????????????? ????????????????????cMessenger?=?msg.replyTo; ?? ????????????????????cMessenger.send(message); ?? ????????????????}?catch ?(RemoteException?e)?{ ?? ?????????????????????? ????????????????????e.printStackTrace(); ?? ????????????????} ?? ????????????????break ; ?? ????????????default : ?? ????????????????super .handleMessage(msg); ?? ????????????} ?? ?? ????????} ?? ????}; ?? ?? ????? ? ?? ????private ?Messenger?mMessenger?=?new ?Messenger(mHandler); ?? ?? ????? ? ?? ????private ?Messenger?cMessenger; ?? ?? ????@Override ?? ????public ?IBinder?onBind(Intent?intent)?{ ?? ?????????? ????????Log.i(TAG,?"onBind" ); ?? ?????????? ????????return ?mMessenger.getBinder(); ?? ????} ?? ?? ????@Override ?? ????public ?void ?onRebind(Intent?intent)?{ ?? ?????????? ????????Log.i(TAG,?"onRebind" ); ?? ?? ????} ?? ?? }?? ?
package com.xwangly.apidemo.app;import java.util.Random;import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;public class MessengerService extends Service {private String TAG = "MessengerService";@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i(TAG, "onDestroy");cMessenger = null;super.onDestroy();}@Overridepublic boolean onUnbind(Intent intent) {// TODO Auto-generated method stubLog.i(TAG, "onUnbind");return super.onUnbind(intent);}static final int MSG_REGISTER_CLIENT = 1;static final int MSG_UNREGISTER_CLIENT = 2;static final int MSG_SET_VALUE = 3;private Random random = new Random();private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubLog.i(TAG, "handleMessage");switch (msg.what) {case MSG_SET_VALUE:try {Message message = Message.obtain(null,MessengerService.MSG_SET_VALUE);message.arg1 = random.nextInt(100);//得到客戶端的信使對象,并向它發送消息cMessenger = msg.replyTo;cMessenger.send(message);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}break;default:super.handleMessage(msg);}}};/*** 自己的信使對象*/private Messenger mMessenger = new Messenger(mHandler);/*** 客戶的信使*/private Messenger cMessenger;@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i(TAG, "onBind");//返回自己信使的bindler,以供客戶端通過這個bindler得到服務端的信使對象(通過new Messenger(bindler))return mMessenger.getBinder();}@Overridepublic void onRebind(Intent intent) {// TODO Auto-generated method stubLog.i(TAG, "onRebind");}}
?MessengerServiceActivities.java
?
Java代碼 ?
package ?com.xwangly.apidemo.app; ???? import ?com.xwangly.apidemo.R; ???? import ?android.app.Activity; ??import ?android.content.ComponentName; ??import ?android.content.Intent; ??import ?android.content.ServiceConnection; ??import ?android.os.Bundle; ??import ?android.os.Handler; ??import ?android.os.IBinder; ??import ?android.os.Message; ??import ?android.os.Messenger; ??import ?android.os.RemoteException; ??import ?android.util.Log; ??import ?android.view.View; ??import ?android.widget.TextView; ???? public ?class ?MessengerServiceActivities?{ ??????public ?static ?class ?Binding?extends ?Activity?implements ?? ????????????View.OnClickListener?{ ?? ????????private ?String?TAG?=?"Binding" ; ?? ?? ????????TextView?mCallbackText; ?? ?? ????????private ?boolean ?isBound; ?? ?? ????????@Override ?? ????????protected ?void ?onCreate(Bundle?savedInstanceState)?{ ?? ?????????????? ????????????super .onCreate(savedInstanceState); ?? ????????????setContentView(R.layout.messenger_service_binding); ?? ????????????findViewById(R.id.bind).setOnClickListener(this ); ?? ????????????findViewById(R.id.unbind).setOnClickListener(this ); ?? ?? ????????????mCallbackText?=?(TextView)?findViewById(R.id.callback); ?? ????????????mCallbackText.setText("Not?attached." ); ?? ?? ????????} ?? ?? ????????private ?Handler?mHandler?=?new ?Handler()?{ ?? ????????????@Override ?? ????????????public ?void ?handleMessage(Message?msg)?{ ?? ????????????????Log.i(TAG,?"handleMessage" ); ?? ????????????????switch ?(msg.what)?{ ?? ????????????????case ?MessengerService.MSG_SET_VALUE: ?? ????????????????????mCallbackText.setText("Received?from?service:?" ?+?msg.arg1); ?? ????????????????????break ; ?? ????????????????default : ?? ????????????????????super .handleMessage(msg); ?? ????????????????} ?? ????????????} ?? ????????}; ?? ?? ????????? ? ?? ????????private ?Messenger?mMessenger; ?? ???????? ?? ????????? ? ?? ????????private ?Messenger?rMessenger; ?? ???????? ?? ????????private ?ServiceConnection?connection?=?new ?ServiceConnection()?{ ?? ?? ????????????public ?void ?onServiceConnected(ComponentName?name,?IBinder?service)?{ ?? ?????????????????? ????????????????Log.i(TAG,?"onServiceConnected" ); ?? ????????????????rMessenger?=?new ?Messenger(service); ?? ????????????????mMessenger?=?new ?Messenger(mHandler); ?? ???????????????? ?? ????????????????sendMessage(); ?? ????????????} ?? ?? ?? ????????????public ?void ?onServiceDisconnected(ComponentName?name)?{ ?? ?????????????????? ????????????????rMessenger?=?null ; ?? ????????????} ?? ????????}; ?? ?? ????????public ?void ?onClick(View?v)?{ ?? ?????????????? ????????????Intent?intent?=?new ?Intent( ?? ????????????????????"com.xwangly.apidemo.app.messenger_service" ); ?? ????????????switch ?(v.getId())?{ ?? ????????????case ?R.id.bind: ?? ????????????????if ?(!isBound)?{ ?? ????????????????????isBound?=?bindService(intent,?connection,?BIND_AUTO_CREATE); ?? ?????????????????????? ????????????????}else ?{ ?? ????????????????????sendMessage(); ?? ????????????????} ?? ????????????????break ; ?? ????????????case ?R.id.unbind: ?? ????????????????if ?(isBound)?{ ?? ????????????????????unbindService(connection); ?? ????????????????????isBound?=?false ; ?? ????????????????} ?? ????????????????break ; ?? ????????????default : ?? ????????????????break ; ?? ????????????} ?? ????????} ?? ???????? ?? ????????? ? ?? ????????private ?void ?sendMessage()?{ ?? ?????????????? ????????????Message?message?=?Message.obtain(null ,?MessengerService.MSG_SET_VALUE); ?? ????????????message.replyTo?=?mMessenger; ?? ????????????try ?{ ?? ????????????????rMessenger.send(message); ?? ????????????}?catch ?(RemoteException?e)?{ ?? ?????????????????? ????????????????e.printStackTrace(); ?? ????????????} ?? ????????} ?? ?? ????} ?? ?? }?? ?
package com.xwangly.apidemo.app;import com.xwangly.apidemo.R;import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.TextView;public class MessengerServiceActivities {public static class Binding extends Activity implementsView.OnClickListener {private String TAG = "Binding";TextView mCallbackText;private boolean isBound;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.messenger_service_binding);findViewById(R.id.bind).setOnClickListener(this);findViewById(R.id.unbind).setOnClickListener(this);mCallbackText = (TextView) findViewById(R.id.callback);mCallbackText.setText("Not attached.");}private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {Log.i(TAG, "handleMessage");switch (msg.what) {case MessengerService.MSG_SET_VALUE:mCallbackText.setText("Received from service: " + msg.arg1);break;default:super.handleMessage(msg);}}};/*** 自己的信使*/private Messenger mMessenger;/*** 遠程服務的信使*/private Messenger rMessenger;private ServiceConnection connection = new ServiceConnection() {public void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubLog.i(TAG, "onServiceConnected");rMessenger = new Messenger(service);mMessenger = new Messenger(mHandler);sendMessage();}public void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubrMessenger = null;}};public void onClick(View v) {// TODO Auto-generated method stubIntent intent = new Intent("com.xwangly.apidemo.app.messenger_service");switch (v.getId()) {case R.id.bind:if (!isBound) {isBound = bindService(intent, connection, BIND_AUTO_CREATE);//isBound = true;}else {sendMessage();}break;case R.id.unbind:if (isBound) {unbindService(connection);isBound = false;}break;default:break;}}/*** 使用服務端的信使向它發送一個消息。*/private void sendMessage() {// TODO Auto-generated method stubMessage message = Message.obtain(null, MessengerService.MSG_SET_VALUE);message.replyTo = mMessenger;try {rMessenger.send(message);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
?AndroidManifest.xml相關配置如下:
?
Xml代碼 ?
< service ?android:name =".app.MessengerService" ?> ??????< intent-filter > ?? ????????< action ?android:name ="com.xwangly.apidemo.app.messenger_service" ?/> ?? ????</ intent-filter > ?? </ service > ????????< activity ?android:name =".app.MessengerServiceActivities$Binding" ?? ??????????????android:label ="@string/activity_messenger_service_binding" ?? ??????????????android:launchMode ="singleTop" > ?? ??????????< intent-filter > ?? ??????????????< action ?android:name ="android.intent.action.MAIN" ?/> ?? ??????????????< category ?android:name ="android.intent.category.LAUNCHER" ?/> ?? ??????????</ intent-filter > ?? ??????</ activity > ?? ?
<service android:name=".app.MessengerService" ><intent-filter><action android:name="com.xwangly.apidemo.app.messenger_service" /></intent-filter></service><activity android:name=".app.MessengerServiceActivities$Binding"android:label="@string/activity_messenger_service_binding"android:launchMode="singleTop"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
?至于layout就不帖了,兩個按鈕一個文本域。
?
轉載于:https://www.cnblogs.com/freeliver54/archive/2011/12/27/2303790.html
總結
以上是生活随笔 為你收集整理的[转]Messenger:使用消息的跨进程通信 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。