1、概述
Messenger是一种轻量级的IPC通信方案,对AIDL进行了封装,可以在不同进程中传递Message对象。
2、使用Messenger通信
Server端代码
public class MessengerService extends Service {
public static final String TAG = "MyMessenger";
public static final int MSG_FROMCLIENT = 1000;
public static final int MSG_FROMSERVER = 1001;
@Override
public void onCreate() {
super.onCreate();
}
private Handler mHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MSG_FROMCLIENT:
Log.d(TAG, "receive message from client:" + msg.getData().getString("msg"));
Messenger messenger = msg.replyTo;
Message message = Message.obtain(null, MSG_FROMSERVER);
Bundle bundle = new Bundle();
bundle.putString("rep", "message form server");
message.setData(bundle);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new Messenger(mHandler).getBinder();
}
}
Service端接收Client端发送的消息,并返回一个消息。Server端要点是创建Handler对象,并在其handleMessage方法中处理Client端发送的消息。如果要返回消息给Client端,则需要Client发送消息时传递Client端的Messenger对象到Server端。同样的Client端要发送消息到Server端,也是通过Server端传递过去的Messenger对象。
Client端代码
public class MainActivity extends AppCompatActivity {
private Handler mHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MessengerService.MSG_FROMSERVER:
Log.d(MessengerService.TAG, "received message from server: " + msg.getData().getString("rep"));
break;
}
}
};
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Messenger messenger = new Messenger(service);
Message message = Message.obtain(null, MessengerService.MSG_FROMCLIENT);
Bundle bundle = new Bundle();
bundle.putString("msg", "message form client");
message.setData(bundle);
message.replyTo = new Messenger(mHandler);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
}
}
bindService时回调onServiceConnected,获取service返回的IBinder对象,由此重构Messenger对象,并用此Messenger对象发送消息给Server端。同时,如果需要处理Server端返回的消息,则需要创建一个Messenger对象并包含Handler对象,将其设置到Message对象的replyTo属性中,并将其传递到Server端,Server端通过这个replyTo获取的Messenger对象发送消息回Client端。
3、Messenger原理探究
从Messenger的使用中可以看出,Messenger通信依赖Binder、Handler和Message。Handler机制是Android线程间通信的机制,BInder是Android进程间通信的机制。
- 构造函数
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
messenger有两个构造函数,分别是传入一个Handler对象和一个IBinder类型的对象作为参数,都会去设置mTarget属性。
先来看一下Handler作为参数的情况,调用的是Handler中的getIMessenger方法。
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
返回的是IMessenger对象,如果Handler中已经设置了该对象则直接返回,如果没有设置,则返回一个MessengerImpl对象。MessengerImpl是Handler中的内部类,继承自IMessenger.Stub,并重写了send方法。
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
可以看出IMessenger是一个aidl接口,里面有一个send方法。
另外一个构造函数就更直接了,直接调用asInterface方法返回一个IMessenger的实例。
- 发送消息
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
调用的是mTarget的send方法,因为mTarget是IMessenger的实例,调用的是Handler中MessengerIml内部类的send方法。从上面的方法中可以看到实际调用的就是Handler中的sendMessage方法。
- 总结
Messenger实际是通过Binder来实现跨进程通信,通过Handler机制来处理消息循环。Messenger封装Handler来进行消息的发送和处理,消息发送后通过Binder完成进程间通信。