Messenger 简介
Messenger(信使) 是一种跨进程通信实现方式,是对 AIDL 的进一步封装,省去了两端创建 AIDL 的过程。
Messenger 用例
服务端
// MessengerRemoteService.java
public class MessengerRemoteService extends Service {
// 服务端 Messenger
private final Messenger serviceMessenger = new Messenger(new MessageHandler());
static class MessageHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
// 客户端 Messenger
Messenger clientMessenger = msg.replyTo;
if (clientMessenger == null) {
return;
}
// 向客户端回复消息
try {
Message message = Message.obtain();
Bundle data = new Bundle();
data.putString("msg", "服务端回复收到来自客户端的消息");
message.setData(data);
clientMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return serviceMessenger.getBinder();
}
}
<!--AndroidManifest.xml-->
<service
android:name=".MessengerRemoteService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.demo.MessengerRemoteService" />
</intent-filter>
</service>
startService(new Intent(this, MessengerRemoteService.class));
客户端
Intent intent1 = new Intent();
intent1.setPackage("com.example.demo");
intent1.setAction("com.example.demo.MessengerRemoteService");
bindService(intent1, new MessengerServiceConnection(), Service.BIND_AUTO_CREATE);
// 客户端 Handler
static class MessengerClientHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
}
static class MessengerServiceConnection implements ServiceConnection {
// 客户端 Messenger
private final Messenger clientMessenger = new Messenger(new MessengerClientHandler());
// 服务端 Messenger
private Messenger serviceMessenger;
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceMessenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
public void send() {
if (serviceMessenger == null) {
return;
}
try {
Message message = Message.obtain();
Bundle data = new Bundle();
message.setData(data);
message.replyTo = clientMessenger;
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
源码解析
首先看一下服务端代码,服务端的 onBind() 方法中创建了一个 服务端Messenger ,传入一个服务端的Handler,然后调用 Messenger 的 getBinder() 方法返回了一个 IBinder。
// Messenger.java
private final IMessenger mTarget;
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public IBinder getBinder() {
return mTarget.asBinder();
}
构造方法中调用了服务端Handler 的 getIMessenger() 方法,获取了一个IMessenger并保存到mTarget。从这里看出 Messager 实际上就是这个 mTarget 的一个代理类。
// Handler.java
@UnsupportedAppUsage
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
getIMessenger() 方法是获取一个 MessengerImpl 单例。
// Handler.MessengerImpl.java
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
MessengerImpl 是 Handler 内置的一个 IMessenger.Stub 实现类。send() 方法就是调用服务端 Handler 的 sendMessage() 方法。等等…Stub
是不是非常熟悉?这个其实就是AIDL为我们生成的 Stub,IMessenger 就是Android为我们定义的AIDL接口。
// IMessenger.aidl
import android.os.Message;
oneway interface IMessenger {
void send(in Message msg);
}
下面看一下客户端代码,客户端连接成功后调用也是创建了一个Messenger,但是传入的不是Handler,而是IBinder。
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
这里的逻辑非常简单,就是利用 AIDL 调用服务端的send()方法。