Messenger可以说是信使,用于不同进程间通信。Messenger是轻量级的IPC,内部是使用了AIDL。
服务端
创建Service,使用Handler参数的Messenger构造方法,具体的数据获取等操作放在Handler#handleMessage()方法中。
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
String message = (String) msg.getData().get("message");
Log.i(TAG, "服务端收到消息:" + message);
Message replyMessage = Message.obtain();
replyMessage.what = 2;
Bundle bundle = new Bundle();
bundle.putString("message","服务端已收到客户端消息,内容如下---"+message);
replyMessage.setData(bundle);
try {
msg.replyTo.send(replyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
}
客户端
客户端使用bindService方式关联启动服务,在ServiceConnection#onServiceConnected回调中获取服务端Messenger。
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//服务端Messenger
serviceMessenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
serviceMessenger = null;
}
};
向服务端Messenger发送消息,并设置回复处理的客户端Messenger。
Message message = Message.obtain();
message.what = 1;
Bundle bundle = new Bundle();
bundle.putString("message", String.format("客户端%s发送信息", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
message.setData(bundle);
//设置回复处理的Messenger
message.replyTo = clientMessenger;
if (serviceMessenger != null) {
try {
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
源码分析
Messenger的构造函数,在创建客户端和服务端Messenger的时候有用到。
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
getIMessenger()的源码可以看到就是一个继承了IMessenger.Stub的类,
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
IMessenger的AIDL如下,里面提供了一个send方法
// /frameworks/base/core/java/android/os/IMessenger.aidl
package android.os;
import android.os.Message;
/** @hide */
oneway interface IMessenger {
void send(in Message msg);
}
IBinder为参数的构造函数和AIDL的很像
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
Messenger和AIDL区别
- 从源码就能看出Messenger就是对AIDL做了个封装,但Messenger只能传递数据,无法调用方法;
- Messenger是以串行方式处理客户端发送的消息,AIDL支持并发处理客户端消息;