<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                #### 2.4.3 使用Messenger **Messenger可以翻譯為信使,顧名思義,通過它可以在不同進程中傳遞Message(信息)對象,在Message中放入我們需要傳遞的數據,就可以輕松地實現數據的進程間傳遞了**。 Messenger是一種**輕量級的IPC方案**,它的**底層實現是AIDL**,為什么這么說呢,我們大致看一下Messenger這個類的構造方法就明白了。下面是Messenger的兩個構造方法,**從構造方法的實現上我們可以明顯看出AIDL的痕跡,不管是IMessenger還是Stub.asInterface,這種使用方法都表明它的底層是AIDL**。 ``` public Messenger(Handler target) { mTarget = target.getIMessenger(); } public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); } ``` **Messenger的使用方法很簡單,它對AIDL做了封裝,使得我們可以更簡便地進行進程間通信。同時,由于它一次處理一個請求,因此在服務端我們不用考慮線程同步的問題,這是因為服務端中不存在并發執行的情形**。 ***** 總之:**Messenger是以串行的方式處理客戶端發來的消息,如果大量的消息同時發送到服務端,服務端仍然只能一個個處理,如果有大量的并發請求,那么用Messenger就不太合適了,同時,Messenger的作用主要是為了*傳遞消息*,很多時候我們可能需要跨進程調用服務端的方法,這種情形用Messenger就無法做到了**。 ***** 實現一個Messenger有如下幾個步驟,分為服務端和客戶端,這里的可不是我們平常意義上的客戶端和服務端,可以理解為兩個進程。 **1.服務端進程** 首先,我們需要在服務端創建一個Service來處理客戶端的連接請求,同時創建一個Handler并通過它來創建一個Messenger對象,然后在Service的onBind中返回這個Messenger對象底層的Binder即可。 **2.客戶端進程** 客戶端進程中,首先要綁定服務端的Service(onCreate方法中調用bindService方法),綁定成功后用服務端返回的IBinder對象(ServiceConnection方法中返回)創建一個Messenger,通過這個Messenger就可以向服務端發送消息了,發消息類型為Message對象。如果需要服務端能夠回應客戶端,就和服務端一樣,我們還需要創建一個Handler并創建一個新的Messenger,并把這個Messenger對象通過Message的replyTo參數傳遞給服務端,服務端通過這個replyTo參數就可以回應客戶端。 這聽起來可能還是有點抽象,不過看了下面的兩個例子,讀者肯定就都明白了。首先,我們來看一個簡單點的例子,在這個例子中服務端無法回應客戶端。 首先看服務端的代碼,這是服務端的典型代碼,可以看到**MessengerHandler用來處理客戶端發送的消息,并從消息中取出客戶端發來的文本信息**。而**mMessenger是一個Messenger對象,它和MessengerHandler相關聯,并在onBind方法中返回它里面的Binder對象**,可以看出,這里**Messenger的作用是將客戶端發送的消息傳遞給MessengerHandler處理**。 * **服務端代碼** ~~~ public class MessengerService extends Service { private static final String TAG = "MessengerService"; //繼承Handler,MessengerHandler用來處理客戶端發送的消息,并從消息中取出客戶端發來的文本信息。 private static class MessengerHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MyConstants.MSG_FROM_CLIENT: Log.i(TAG, "receive msg from Client:" + msg.getData().getString("msg")); /** * 因為我們的Messenger是通過客戶端來獲取的,而在客戶端那邊這個Messenger是以Handler為參數創建的, * 所以在服務端通過客戶端的Messenger發送消息后,在客戶端的Handler就會處理這條消息, * 嘻嘻,就達到了消息傳送的目的。 */ Messenger client = msg.replyTo; Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE); Bundle bundle = new Bundle(); bundle.putString("reply", "嗯,你的消息我已經收到,稍后會回復你。"); relpyMessage.setData(bundle); try { client.send(relpyMessage); } catch (RemoteException e) { e.printStackTrace(); } break; default: super.handleMessage(msg); } } } //這是我們服務端自己的Messenger,它是以上面的Handler對象為參數創建的, //這個Messenger是要通過綁定該服務器的時候onBind方法傳遞給客戶端,然后客戶端獲取了該Messenger, //再以該Messenger來發送消息,這樣服務端就可以接收到該消息并處理。 private final Messenger mMessenger = new Messenger(new MessengerHandler()); //這個方法是在綁定服務的過程中調用的并將結果返回給客戶端的,所以通過onBind方法客戶端就可以獲取我們Messenger的Binder對象了, //然后客戶端可以根據該Binder對象來創建一個Messenger,這樣客戶端中用的Messenger和這里的Messenger就是向對應的了。 @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); } } ~~~ 然后,注冊service,讓其運行在單獨的進程中: ``` <service android:name="com.ryg.chapter_2.messenger.MessengerService" android:process=":remote" > ``` 接下來再看看客戶端的實現,客戶端的實現也比較簡單,首先需要綁定遠程進程的MessengerService,綁定成功后,根據服務端返回的binder對象創建Messenger對象并使用此對象向服務端發送消息。下面的代碼在Bundle中向服務端發送了一句話,在上面的服務端代碼中會打印出這句話。 **客戶端代碼** ``` public class MessengerActivity extends Activity { private static final String TAG = "MessengerActivity"; private Messenger mService; //準備一個接收消息的Messenger和Handler //這是客戶端自己的Messenger,傳遞給服務端,讓服務端返回消息用的。 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, "receive msg from Service:" + msg.getData ().getString ("reply")); break; default: super.handleMessage (msg); } } } /** * 這個是客戶端用來綁定服務端用的,在綁定過程中會調用onServiceConnected,它的第二個參數IBinder service, * 就是在服務端中onBind方法返回的結果,這個結果是服務端的Messenger對象的Binder對象, * 然后客戶端通過這個Binder對象就可以創建一個Messenger, * 所以就是在綁定服務的過程中將服務端的Messenger傳遞給了客戶端,建立起了兩者之間的橋梁 */ 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", "hello, this is client."); msg.setData (data); //把接收服務端回復的Messenger通過Message的replyTo參數傳遞給服務端 msg.replyTo = mGetReplyMessenger; try { mService.send (msg); } catch (RemoteException e) { e.printStackTrace (); } } public void onServiceDisconnected(ComponentName className) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView (R.layout.activity_messenger); Intent intent = new Intent ("com.ryg.MessengerService.launch"); //在bindService的時候,服務端會通過onBind方法返回一個包含了服務端業務調用的Binder對象, //通過這個對象,客戶端就可以獲取服務端提供的服務或者數據, bindService (intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { unbindService (mConnection); super.onDestroy (); } } ``` 最后,我們運行程序,看一下log,很顯然,服務端成功收到了客戶端所發來的問候語:“hello, this is client.”。 ``` I/MessengerService( 1037): receive msg from Client:hello, this is client. ``` 通過上面的例子可以看出,**在Messenger(信使)中進行數據傳遞必須將數據放入Message(信息)中,而Messenger和Message都實現了Parcelable接口,因此可以跨進程傳輸**。簡單來說,**Message中所支持的數據類型就是Messenger所支持的傳輸類型**。實際上,**通過Messenger來傳輸Message,Message中能使用的載體只有what、arg1、arg2、Bundle以及replyTo。Message中的另一個字段object在同一個進程中是很實用的,但是在進程間通信的時候,在Android 2.2以前object字段不支持跨進程傳輸,即便是2.2以后,也僅僅是系統提供的實現了Parcelable接口的對象才能通過它來傳輸。這就意味著我們自定義的Parcelable對象是無法通過object字段來傳輸的**,讀者可以試一下。**非系統的Parcelable對象的確無法通過object字段來傳輸,這也導致了object字段的實用性大大降低**,所幸我們還有Bundle,**Bundle中可以支持大量的數據類型**。 上面的例子演示了如何在服務端接收客戶端中發送的消息,但是有時候我們還需要能回應客戶端,下面就介紹如何實現這種效果。還是采用上面的例子,但是稍微做一下修改,每當客戶端發來一條消息,服務端就會自動回復一條“嗯,你的消息我已經收到,稍后會回復你。”,這很類似郵箱的自動回復功能。 首先看服務端的修改,服務端只需要修改MessengerHandler,當收到消息后,會立即回復一條消息給客戶端。 ``` //繼承Handler,MessengerHandler用來處理客戶端發送的消息,并從消息中取出客戶端發來的文本信息。 private static class MessengerHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MyConstants.MSG_FROM_CLIENT: Log.i(TAG, "receive msg from Client:" + msg.getData().getString("msg")); /** * 因為我們的Messenger是通過客戶端來獲取的,而在客戶端那邊這個Messenger是以Handler為參數創建的, * 所以在服務端通過客戶端的Messenger發送消息后,在客戶端的Handler就會處理這條消息, * 嘻嘻,就達到了消息傳送的目的。 */ Messenger client = msg.replyTo; Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE); Bundle bundle = new Bundle(); bundle.putString("reply", "嗯,你的消息我已經收到,稍后會回復你。"); relpyMessage.setData(bundle); try { client.send(relpyMessage); } catch (RemoteException e) { e.printStackTrace(); } break; default: super.handleMessage(msg); } } } ``` 接著再看客戶端的修改,為了接收服務端的回復,客戶端也需要準備一個接收消息的Messenger和Handler,如下所示。 ``` //準備一個接收消息的Messenger和Handler //這是客戶端自己的Messenger,傳遞給服務端,讓服務端返回消息用的。 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, "receive msg from Service:" + msg.getData ().getString ("reply")); break; default: super.handleMessage (msg); } } } ``` 除了上述修改,還有很關鍵的一點,當客戶端發送消息的時候,需要把接收服務端回復的Messenger通過Message的replyTo參數傳遞給服務端,如下所示。 ``` 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", "hello, this is client."); msg.setData (data); //把接收服務端回復的Messenger通過Message的replyTo參數傳遞給服務端 msg.replyTo = mGetReplyMessenger; try { .send (msg); } catch (RemoteException e) { e.printStackTrace (); } } public void onServiceDisconnected(ComponentName className) { } }; ``` 通過上述修改,我們再運行程序,然后看一下log,很顯然,客戶端收到了服務端的回復“嗯,你的消息我已經收到,稍后會回復你。”,這說明我們的功能已經完成。 ``` I/MessengerService( 1419): receive msg from Client:hello, this is client. I/MessengerActivity( 1404): receive msg from Service:嗯,你的消息我已經收到, ``` 稍后會回復你。 到這里,我們已經把采用Messenger進行進程間通信的方法都介紹完了,讀者可以試著通過Messenger來實現更復雜的跨進程通信功能。下面給出一張Messenger的工作原理圖以方便讀者更好地理解Messenger,如圖2-6所示。 :-: ![](https://img.kancloud.cn/7f/9a/7f9afd1a086ab10578c59554d4f14dcc_1437x530.png) 圖2-6 Messenger的工作原理 關于進程間通信,可能有的讀者會覺得筆者提供的示例都是針對同一個應用的,有沒有針對不同應用的?是這樣的,之所以選擇在同一個應用內進行進程間通信,是因為操作起來比較方便,但是效果和在兩個應用間進行進程間通信是一樣的。在本章剛開始就說過,**同一個應用的不同組件,如果它們運行在不同進程中,那么和它們分別屬于兩個應用沒有本質區別**,關于這點需要深刻理解,因為這是理解進程間通信的基礎。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看