Messenger:使用消息的跨进程通信

Messenger:信使

官方文档解释:它引用了一个Handler对象,以便others能够向它发送消息(使用mMessenger.send(Message msg)方法)。该类允许跨进程间基于Message的通信(即两个进程间可以通过Message进行通信),在服务端使用Handler创建一个 Messenger,客户端持有这个Messenger就可以与服务端通信了。

 

以前我们使用Handler+Message的方式进行通信,都是在同一个进程中,从线程持有一个主线程的Handler对象,并向主线程发送消息。

而Android既然可以使用bindler机制进行跨进行通信,所以我们当然可以将Handler与bindler结合起来进行跨进程发送消息。

查看API就可以发现,Messenger就是这种方式的实现。

一般使用方法如下:

1。远程通过

Java代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. mMessenger = new Messenger(mHandler)  
mMessenger = new Messenger(mHandler)

 创建一个信使对象

2。客户端使用bindlerService请求连接远程

3。远程onBind方法返回一个bindler

Java代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. return mMessenger.getBinder();  
return mMessenger.getBinder();

 4.客户端使用远程返回的bindler得到一个信使(即得到远程信使)

Java代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. public void onServiceConnected(ComponentName name, IBinder service) {  
  2.     rMessenger = new Messenger(service);  
  3.      ......  
  4. }  
   public void onServiceConnected(ComponentName name, IBinder service) {     rMessenger = new Messenger(service);         ......    }

 这里虽然是new了一个Messenger,但我们查看它的实现

Java代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. /** 
  2.  * Create a Messenger from a raw IBinder, which had previously been 
  3.  * retrieved with {@link #getBinder}. 
  4.  *  
  5.  * @param target The IBinder this Messenger should communicate with. 
  6.  */  
  7. public Messenger(IBinder target) {  
  8.     mTarget = IMessenger.Stub.asInterface(target);  
  9. }  
    /**      * 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代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. //得到客户端的信使对象,并向它发送消息  
  2. cMessenger = msg.replyTo;  
  3. cMessenger.send(message);  
//得到客户端的信使对象,并向它发送消息 cMessenger = msg.replyTo; cMessenger.send(message);

 即完成了从服务端向客户端发送消息的功能,这样客服端可以在自己的Handler对象的handlerMessage方法中接收服务端发送来的message进行处理。

双向通信宣告完成。

 

下面改写ApiDemos工程实现Messenger通信

MessengerService.java

Java代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. package com.xwangly.apidemo.app;  
  2.   
  3. import java.util.Random;  
  4.   
  5. import android.app.Service;  
  6. import android.content.Intent;  
  7. import android.os.Handler;  
  8. import android.os.IBinder;  
  9. import android.os.Message;  
  10. import android.os.Messenger;  
  11. import android.os.RemoteException;  
  12. import android.util.Log;  
  13.   
  14. public class MessengerService extends Service {  
  15.     private String TAG = "MessengerService";  
  16.   
  17.     @Override  
  18.     public void onDestroy() {  
  19.         // TODO Auto-generated method stub  
  20.         Log.i(TAG, "onDestroy");  
  21.         cMessenger = null;  
  22.         super.onDestroy();  
  23.     }  
  24.   
  25.     @Override  
  26.     public boolean onUnbind(Intent intent) {  
  27.         // TODO Auto-generated method stub  
  28.         Log.i(TAG, "onUnbind");  
  29.         return super.onUnbind(intent);  
  30.     }  
  31.   
  32.     static final int MSG_REGISTER_CLIENT = 1;  
  33.     static final int MSG_UNREGISTER_CLIENT = 2;  
  34.     static final int MSG_SET_VALUE = 3;  
  35.   
  36.     private Random random = new Random();  
  37.   
  38.     private Handler mHandler = new Handler() {  
  39.   
  40.         @Override  
  41.         public void handleMessage(Message msg) {  
  42.             // TODO Auto-generated method stub  
  43.             Log.i(TAG, "handleMessage");  
  44.             switch (msg.what) {  
  45.             case MSG_SET_VALUE:  
  46.                 try {  
  47.                     Message message = Message.obtain(null,  
  48.                             MessengerService.MSG_SET_VALUE);  
  49.                     message.arg1 = random.nextInt(100);  
  50.                       
  51.                     //得到客户端的信使对象,并向它发送消息  
  52.                     cMessenger = msg.replyTo;  
  53.                     cMessenger.send(message);  
  54.                 } catch (RemoteException e) {  
  55.                     // TODO Auto-generated catch block  
  56.                     e.printStackTrace();  
  57.                 }  
  58.                 break;  
  59.             default:  
  60.                 super.handleMessage(msg);  
  61.             }  
  62.   
  63.         }  
  64.     };  
  65.   
  66.     /** 
  67.      * 自己的信使对象 
  68.      */  
  69.     private Messenger mMessenger = new Messenger(mHandler);  
  70.   
  71.     /** 
  72.      * 客户的信使 
  73.      */  
  74.     private Messenger cMessenger;  
  75.   
  76.     @Override  
  77.     public IBinder onBind(Intent intent) {  
  78.         // TODO Auto-generated method stub  
  79.         Log.i(TAG, "onBind");  
  80.         //返回自己信使的bindler,以供客户端通过这个bindler得到服务端的信使对象(通过new Messenger(bindler))  
  81.         return mMessenger.getBinder();  
  82.     }  
  83.   
  84.     @Override  
  85.     public void onRebind(Intent intent) {  
  86.         // TODO Auto-generated method stub  
  87.         Log.i(TAG, "onRebind");  
  88.   
  89.     }  
  90.   
  91. }  
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() {   // TODO Auto-generated method stub   Log.i(TAG, "onDestroy");   cMessenger = null;   super.onDestroy();  }   @Override  public boolean onUnbind(Intent intent) {   // TODO Auto-generated method stub   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) {    // TODO Auto-generated method stub    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) {      // TODO Auto-generated catch block      e.printStackTrace();     }     break;    default:     super.handleMessage(msg);    }    }  };   /**   * 自己的信使对象   */  private Messenger mMessenger = new Messenger(mHandler);   /**   * 客户的信使   */  private Messenger cMessenger;   @Override  public IBinder onBind(Intent intent) {   // TODO Auto-generated method stub   Log.i(TAG, "onBind");   //返回自己信使的bindler,以供客户端通过这个bindler得到服务端的信使对象(通过new Messenger(bindler))   return mMessenger.getBinder();  }   @Override  public void onRebind(Intent intent) {   // TODO Auto-generated method stub   Log.i(TAG, "onRebind");   }  } 

 MessengerServiceActivities.java

Java代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. package com.xwangly.apidemo.app;  
  2.   
  3. import com.xwangly.apidemo.R;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.ComponentName;  
  7. import android.content.Intent;  
  8. import android.content.ServiceConnection;  
  9. import android.os.Bundle;  
  10. import android.os.Handler;  
  11. import android.os.IBinder;  
  12. import android.os.Message;  
  13. import android.os.Messenger;  
  14. import android.os.RemoteException;  
  15. import android.util.Log;  
  16. import android.view.View;  
  17. import android.widget.TextView;  
  18.   
  19. public class MessengerServiceActivities {  
  20.     public static class Binding extends Activity implements  
  21.             View.OnClickListener {  
  22.         private String TAG = "Binding";  
  23.   
  24.         TextView mCallbackText;  
  25.   
  26.         private boolean isBound;  
  27.   
  28.         @Override  
  29.         protected void onCreate(Bundle savedInstanceState) {  
  30.             // TODO Auto-generated method stub  
  31.             super.onCreate(savedInstanceState);  
  32.             setContentView(R.layout.messenger_service_binding);  
  33.             findViewById(R.id.bind).setOnClickListener(this);  
  34.             findViewById(R.id.unbind).setOnClickListener(this);  
  35.   
  36.             mCallbackText = (TextView) findViewById(R.id.callback);  
  37.             mCallbackText.setText("Not attached.");  
  38.   
  39.         }  
  40.   
  41.         private Handler mHandler = new Handler() {  
  42.             @Override  
  43.             public void handleMessage(Message msg) {  
  44.                 Log.i(TAG, "handleMessage");  
  45.                 switch (msg.what) {  
  46.                 case MessengerService.MSG_SET_VALUE:  
  47.                     mCallbackText.setText("Received from service: " + msg.arg1);  
  48.                     break;  
  49.                 default:  
  50.                     super.handleMessage(msg);  
  51.                 }  
  52.             }  
  53.         };  
  54.   
  55.         /** 
  56.          * 自己的信使 
  57.          */  
  58.         private Messenger mMessenger;  
  59.           
  60.         /** 
  61.          * 远程服务的信使 
  62.          */  
  63.         private Messenger rMessenger;  
  64.           
  65.         private ServiceConnection connection = new ServiceConnection() {  
  66.   
  67.             public void onServiceConnected(ComponentName name, IBinder service) {  
  68.                 // TODO Auto-generated method stub  
  69.                 Log.i(TAG, "onServiceConnected");  
  70.                 rMessenger = new Messenger(service);  
  71.                 mMessenger = new Messenger(mHandler);  
  72.                   
  73.                 sendMessage();  
  74.             }  
  75.   
  76.   
  77.             public void onServiceDisconnected(ComponentName name) {  
  78.                 // TODO Auto-generated method stub  
  79.                 rMessenger = null;  
  80.             }  
  81.         };  
  82.   
  83.         public void onClick(View v) {  
  84.             // TODO Auto-generated method stub  
  85.             Intent intent = new Intent(  
  86.                     "com.xwangly.apidemo.app.messenger_service");  
  87.             switch (v.getId()) {  
  88.             case R.id.bind:  
  89.                 if (!isBound) {  
  90.                     isBound = bindService(intent, connection, BIND_AUTO_CREATE);  
  91.                     //isBound = true;  
  92.                 }else {  
  93.                     sendMessage();  
  94.                 }  
  95.                 break;  
  96.             case R.id.unbind:  
  97.                 if (isBound) {  
  98.                     unbindService(connection);  
  99.                     isBound = false;  
  100.                 }  
  101.                 break;  
  102.             default:  
  103.                 break;  
  104.             }  
  105.         }  
  106.           
  107.         /** 
  108.          * 使用服务端的信使向它发送一个消息。 
  109.          */  
  110.         private void sendMessage() {  
  111.             // TODO Auto-generated method stub  
  112.             Message message = Message.obtain(null, MessengerService.MSG_SET_VALUE);  
  113.             message.replyTo = mMessenger;  
  114.             try {  
  115.                 rMessenger.send(message);  
  116.             } catch (RemoteException e) {  
  117.                 // TODO Auto-generated catch block  
  118.                 e.printStackTrace();  
  119.             }  
  120.         }  
  121.   
  122.     }  
  123.   
  124. }  
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) {    // TODO Auto-generated method stub    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) {     // TODO Auto-generated method stub     Log.i(TAG, "onServiceConnected");     rMessenger = new Messenger(service);     mMessenger = new Messenger(mHandler);          sendMessage();    }      public void onServiceDisconnected(ComponentName name) {     // TODO Auto-generated method stub     rMessenger = null;    }   };    public void onClick(View v) {    // TODO Auto-generated method stub    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);      //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 stub    Message message = Message.obtain(null, MessengerService.MSG_SET_VALUE);    message.replyTo = mMessenger;    try {     rMessenger.send(message);    } catch (RemoteException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }   }   }  } 

 AndroidManifest.xml相关配置如下:

Xml代码  收藏代码Messenger:使用消息的跨进程通信 - tuchengju - tuchengju的博客
  1. <service android:name=".app.MessengerService" >  
  2.     <intent-filter>  
  3.         <action android:name="com.xwangly.apidemo.app.messenger_service" />  
  4.     </intent-filter>  
  5. </service>  
  6.       <activity android:name=".app.MessengerServiceActivities$Binding"  
  7.               android:label="@string/activity_messenger_service_binding"  
  8.               android:launchMode="singleTop">  
  9.           <intent-filter>  
  10.               <action android:name="android.intent.action.MAIN" />  
  11.               <category android:name="android.intent.category.LAUNCHER" />  
  12.           </intent-filter>  
  13.       </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就不帖了,两个按钮一个文本域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值