前言
Messenger翻译为“信使”,顾名思义,可以在不同进程中传递Message对象。Messenger是一种轻量级IPC方案,底层实现也是AIDL,只是对AIDL做了封装。Messenger的使用相对于AIDL方便多,因为Messenger是Android系统中自带的类,服务端和客户端都不用创建AIDL文件。Messenger会持有一个Handler,这个Handler用于处理接受到的信息,在服务端和客户端通过Messenger实现双方通信。
构造方法
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
明显看出使用了aidl的痕迹。
服务端进程
构建一个运行在独立进程中的服务端Service:
public class MessengerService extends Service {
private static final String TAG = "MessagerService";
/**
* 处理来自客户端的消息,并用于构建Messenger
*/
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case MESSAGE_FROM_CLIENT:
Log.e(TAG, "receive message from client:" + message.getData().getString("msg"));
//获取客户端传递过来的Messenger,通过这个Messenger回传消息给客户端
Messenger client = message.replyTo;
//当然,回传消息还是要通过message
Message msg = Message.obtain(null, Constant.MESSAGE_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("msg", "hello client, I have received your message!");
msg.setData(bundle);
try {
client.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(message);
break;
}
}
}
/**
* 构建Messenger对象
*/
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
//将Messenger对象的Binder返回给客户端
return mMessenger.getBinder();
}
}
注册service,当然要设置在不同的进程
<service
android:name="com.kanghanbin.service.MessengerService"
android:process=":remote" />
客户端进程
public class MessengerActivity extends AppCompatActivity {
private static final String TAG = "MessengerActivity";
private Messenger mService;
/**
* 客户端Messenger对象
*/
private Messenger mClientMessenger = new Messenger(new MessengerHandler());
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "ServiceConnection-->" + System.currentTimeMillis());
//通过服务端返回的Binder创建Messenger
mService = new Messenger(iBinder);
//创建消息,通过Bundle传递数据
Message message = Message.obtain(null, MESSAGE_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("msg", "hello service,this is client");
message.setData(bundle);
//将客户端的Messenger对象传递给服务端
message.replyTo = mClientMessenger;
try {
//向服务端发送消息
mService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "onServiceDisconnected-->binder died");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
//绑定服务
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
//解绑服务
unbindService(mConnection);
super.onDestroy();
}
}
客户端发送信息
使用Messenger向服务端发送信息,使用的是Messenger.send(Message)
方法,这个方法具体实现如下:
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
方法内部调用mTarget.send(Message)
方法,在Messenger中,mTarget
是在构造方法里面被赋值的。
总结
- 使用Messager来传递Message,Message中能使用的字段只有what、arg1、arg2、Bundle和replyTo,自定义的Parcelable对象无法通过object字段来传输
- Message中的Bundle支持多种数据类型,replyTo字段用于传输Messager对象,以便进程间相互通信
- Messager以串行的方式处理客户端发来的消息,不适合有大量并发的请求
- Messager方法只能传递消息,不能跨进程调用方法