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

转载自:http://xwangly.iteye.com/blog/1109424

这篇文章题目其实做好叫:Activity和Service通过Messenger通讯。

 

 

Messenger:信使

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

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

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

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

一般使用方法如下:

1。远程通过

Java代码 
  1. mMessenger = new Messenger(mHandler) 
mMessenger = new Messenger(mHandler)

创建一个信使对象

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

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

Java代码 
  1. return mMessenger.getBinder(); 
return mMessenger.getBinder();

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

Java代码 
  1. public void onServiceConnected(ComponentName name, IBinder service) { 
  2.     rMessenger = new Messenger(service); 
  3.      ...... 
			public void onServiceConnected(ComponentName name, IBinder service) {
				rMessenger = new Messenger(service);
        ......
			}

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

Java代码 
  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); 
    /**
     * 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代码 
  1. //得到客户端的信使对象,并向它发送消息 
  2. cMessenger = msg.replyTo; 
  3. cMessenger.send(message); 
//得到客户端的信使对象,并向它发送消息
cMessenger = msg.replyTo;
cMessenger.send(message);

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

双向通信宣告完成。

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

MessengerService.java

Java代码 
  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.  
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代码 
  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.  
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代码 
  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> 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值