Messenger可以翻译为信使,顾名思义通过它可以实现跨进程传递Message对象,在Message中放入我们需要传递的对象就可以实现进程间通信了。这是一种轻量级的IPC方案,相比于AIDL使用更加简单。
1.服务器实现
端废话不多说先上服务器源码 MessengerService.java
package com.ryg.chapter_2.messenger;
import com.ryg.chapter_2.model.User;
import com.ryg.chapter_2.utils.MyConstants;
import android.app.Service;
import android.content.Intent;
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;
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
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 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);
}
}
}
@Override
public IBinder onBind(Intent intent) {
return new Messenger(new MessengerHandler()).getBinder();
}
}
概括起来:主要实现了一个Handler对象,用来构造Messenger对象,在Service的onBind方法中返回该对象getBinder方法。
2.客户端端实现
客户端代码MessengerActivity.java
package com.ryg.chapter_2.messenger;
import com.ryg.chapter_2.R;
import com.ryg.chapter_2.utils.MyConstants;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
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;
public class MessengerActivity extends Activity {
private static final String TAG = "MessengerActivity";
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);
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
Messenger 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);
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(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}
跟AIDL获取远程Service调用过程差不多,新建一个ServiceConnection并在其onServiceConnected()中获取远程Messenger,把需要传递的对象放在Message中通过远程Messenger发送,即发送消息给服务器端处理。这里的bindService第一个参数用的是隐式的Intent,如果在一个应用用显式Intent也是OK的。
在这里我们分别看下Messenger在服务器端和客户端的实现方法
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
从构造方法明显看到AIDL的痕迹,这表明Message底层实现就是AIDL,Message就是对AIDL的简单封装,服务器端每次只能处理一个请求,没有并发的可能。
3.使用总结
1.服务器Service,mMessenger = new Messenger(new Handler()), 重写onBind方法返回mMessenger.getBinder()实例;
2.客户端:ServiceConnection实例serviceConnection onServiceConnected方法得到IBinder(android.os.BinderProxy), android.os.Messenger mMessenger = new Messenger(service); 调用方法mMessenger.send(msg)与服务器端通信
3.服务器端与客户端通信 获取客户端接收Messenger,Messenger clientMessenger = msg.replyTo; clientMessenger.send(relpyMessage); 消息client的mMessenger的handler处理
2.客户端:ServiceConnection实例serviceConnection onServiceConnected方法得到IBinder(android.os.BinderProxy), android.os.Messenger mMessenger = new Messenger(service); 调用方法mMessenger.send(msg)与服务器端通信
3.服务器端与客户端通信 获取客户端接收Messenger,Messenger clientMessenger = msg.replyTo; clientMessenger.send(relpyMessage); 消息client的mMessenger的handler处理
工程中需要修改配置对应客户端Activity
<activity
android:name=".messenger.MessengerActivity"
android:label="@string/title_activity_messenger" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>