Android进程间的通信之Messenger

知识就是力量,时间就是生命。这篇文章主要讲述Android进程间的通信之Messenger相关的知识,希望能为你提供帮助。
android进程间的通信方式可以通过以下两种方式完成:

1 Android接口定义语言(AIDL) 2 使用Messenger绑定服务

本文我们将学习使用Messenger绑定服务的方式进行进程间的通信。


Android AIDL和Messenger区别
使用Messenger是执行进程间通信最简单的方法,因为Messenger会在单一线程中创建包含所有请求的队列,这样您就不必对服务进行线程安全设计。而纯粹的AIDL接口会同时向服务发送多个请求,服务随后必须应对多线程处理。AIDL通常应用在服务被设计到单独的应用中的场景(即服务端可客户端不属于同一个app的情况),而Messenger通常应用在同一app的不同进程的场景中。
Messenger基本思想
服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler(具体来讲:是Handler的子类)来创建Messenger,在onBind时返回Messenger的binder(调用Messenger的getBinder()方法,该方法返回一个IBinder对象,客户端将通过该对象作为参数创建一个Messenger对象用于与服务端进行通信)。
Messenger使用步骤
1、服务端实现一个Handler,由其接收来自客户端的每个调用的回调 2、使用第1步的Handler的实例作为target创建Messenger对象(即该Messenger持有了对Handler的引用) 3、使用Messenger创建一个IBinder(通过调用Messenger的getBinder()方法),服务端的onBind()方法中将其返回到客户端 4、客户端使用IBinder将Messenger(引用服务端的Handler实例)实例化,然后使用后者将Message对象发送给服务端 5、服务端在其Handler中接收每个Message

这样,客户端并没有调用服务端的“方法”,而客户端传递的消息(Message对象)是服务端在其Handler中接收到的。
如果想让服务端对客户端发回响应,则还需要在客户端中创建一个持有客户端Handler实现类的Messenger,当客户端收到onServiceConnected()回调时,在向服务发送的Message时,send()方法的replyTo参数中需包含客户端的Messenger。这样,客户端就可在其Handler实现类中接收到来自服务端的响应消息。
简单示例
AndroidMainfest.xml
< application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > < activity android:name="yf.exam.client.MainActivity" android:label="@string/app_name" > < intent-filter> < action android:name="android.intent.action.MAIN" /> < category android:name="android.intent.category.LAUNCHER" /> < /intent-filter> < /activity> < service android:name=".MessengerService" android:process=":custom_process"/> < /application>

 
在上面的配置文件中,service的android:process属性用于在一个单独进程中启动service,看如下图片:
Android进程间的通信之Messenger

文章图片

布局文件很简单,这里只有一个按钮,用于向服务端发送消息并显示服务端响应内容,这里不再给出。
客户端:MainActivity
1 public class MainActivity extends Activity { 2private static final int REPLY_MSG_ID = 2; 3private boolean mServiceConnected = false; 4private Button btn = null; 5//用于向Service端发送消息的Messenger 6private Messenger mBoundServiceMessenger = null; 7//用于接收Service发送消息的Messenger 8private final Messenger mReceiveMessenger = new Messenger(new ReceiveMessHandler(this)); 9private ServiceConnection conn = new ServiceConnection() { 10@Override 11public void onServiceDisconnected(ComponentName name) { 12mBoundServiceMessenger = null; 13mServiceConnected = false; 14} 15 16@Override 17public void onServiceConnected(ComponentName name, IBinder service) { 18mBoundServiceMessenger = new Messenger(service); 19mServiceConnected = true; 20} 21}; 22@Override 23protected void onCreate(Bundle savedInstanceState) { 24super.onCreate(savedInstanceState); 25setContentView(R.layout.activity_main); 26btn = (Button)findViewById(R.id.button); 27bindService(new Intent(this, MessengerService.class), conn, Context.BIND_AUTO_CREATE); 28btn.setOnClickListener(new View.OnClickListener() { 29@Override 30public void onClick(View v) { 31if(mServiceConnected){ 32//获取消息对象 33Message msg = Message.obtain(null, 1, 0, 0); 34try{ 35//replyTo参数包含客户端Messenger 36msg.replyTo = mReceiveMessenger; 37//向Service端发送消息 38mBoundServiceMessenger.send(msg); 39}catch(RemoteException re){ 40re.printStackTrace(); 41} 42} 43} 44}); 45} 46@Override 47protected void onDestroy() { 48super.onDestroy(); 49if(mServiceConnected){ 50unbindService(conn); 51mServiceConnected = false; 52} 53} 54/** 55* 客户端实现一个Handler用于接收服务端返回的响应 56* @author Administrator 57* 58*/ 59static class ReceiveMessHandler extends Handler{ 60//持有当前Activity的弱引用,避免内存泄露 61private final WeakReference< MainActivity> mActivity; 62public ReceiveMessHandler(MainActivity activity){ 63mActivity = new WeakReference< MainActivity> (activity); 64} 65@Override 66public void handleMessage(Message msg) { 67switch(msg.what){ 68case REPLY_MSG_ID: 69Toast.makeText(mActivity.get(), msg.getData().getString("msg"), Toast.LENGTH_SHORT).show(); 70break; 71} 72} 73} 74 }

服务端:MessengerService.java
1 public class MessengerService extends Service { 2private static final int REPLY_MSG_ID = 2; 3private static final int MSG_ID = 1; 4static class BoundServiceHandler extends Handler{ 5private final WeakReference< MessengerService> mService; 6public BoundServiceHandler(MessengerService service){ 7mService = new WeakReference< MessengerService> (service); 8} 9@Override 10public void handleMessage(Message msg) { 11switch(msg.what){ 12case MSG_ID: 13Messenger replyMessenger = msg.replyTo; 14Message replyMsg = Message.obtain(null, REPLY_MSG_ID); 15//向客户端响应的消息内容 16Bundle b = new Bundle(); 17b.putString("msg", "this is the message reply from service"); 18replyMsg.setData(b); 19try{ 20replyMessenger.send(replyMsg); 21}catch(RemoteException re){ 22re.printStackTrace(); 23} 24break; 25default: 26super.handleMessage(msg); 27} 28} 29} 30private final Messenger mMessenger = new Messenger(new BoundServiceHandler(this)); 31@Override 32public IBinder onBind(Intent intent) { 33Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); 34return mMessenger.getBinder(); 35} 36 }

【Android进程间的通信之Messenger】此外,上述例子中所有的Handler的实现类都被声明为static并使用Service或Activity的WeakReference。如果不这样做,编译器会给出警告信息“This handler class should be static or leaks might occur”。通过使用弱引用的方式,就允许Service或Activity进行垃圾收集了。



    推荐阅读