刚开始接触Messenger和Handler时,总感觉他俩有点相似,因为它俩都有“send(Message message)”方法,并且处理消息都是串行的,后来看了源码才知道,它俩何止是相似,Messenger完全就是Handler支持跨进程调用的增强版。
Messenger的基本用法
服务端:MyService.kt
class MyService : Service() {
val mServiceMessenger = Messenger(ServiceMessengerHandler(Looper.getMainLooper()))
class ServiceMessengerHandler(looper: Looper) : Handler(looper) {
override fun handleMessage(msg: Message) {
val messageString = msg.data.getString("message")
Log.d("mytestmessenger", "Receive Client message: $messageString")
val message = Message.obtain()
val data = Bundle()
data.putString("message", "hello, I am Service!")
message.data = data
msg.replyTo.send(message)
}
}
override fun onBind(intent: Intent?): IBinder? {
return mServiceMessenger.binder
}
}
配置文件:AndroidManifest.xml
声明在另一个进程中运行
<service android:name=".MyService"
android:process=":myService"/>
客户端:MainActivity.kt
var mClientMessenger = Messenger(ClientMessengerHandler(Looper.getMainLooper()))
class ClientMessengerHandler(looper: Looper) : Handler(looper) {
override fun handleMessage(msg: Message) {
val messageString = msg.data.getString("message")
Log.d("mytestmessenger", "Receive Service message: $messageString")
}
}
fun testMessenger() {
val intent = Intent(this, MyService::class.java)
val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val serviceMessenger = Messenger(service)
val message = Message.obtain()
val data = Bundle()
data.putString("message", "hello, I am Client!")
message.data = data
message.replyTo = mClientMessenger
serviceMessenger.send(message)
}
override fun onServiceDisconnected(name: ComponentName?) {
}
}
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
Messenger源码分析
Messenger.java代码整体结构
class Messenger implements Parcelable {
private final IMessenger mTarget;
/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
/**
* Send a Message to this Messenger's Handler.
*
* @param message The Message to send. Usually retrieved through
* {@link Message#obtain() Message.obtain()}.
*
* @throws RemoteException Throws DeadObjectException if the target
* Handler no longer exists.
*/
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
/**
* Retrieve the IBinder that this Messenger is using to communicate with
* its associated Handler.
*
* @return Returns the IBinder backing this Messenger.
*/
public IBinder getBinder() {
return mTarget.asBinder();
}
... ...
}
从Messenger的代码结构上可以看出:
- 它实现了Parcelable接口,所以在跨进程通信时,可以将Client的Messenger对象作为Message的replyTo参数传递到服务端
- 构造方法有两个,一个是传入Handler,另一个是传入IBinder,不管是传入哪个,都是为了拿到【IMessenger】接口,那么【IMessenger】接口是什么呢?
- send(Message message) :发送消息
- getBinder():将IMessenger接口转为IBinder
IMessenger接口
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
从"mTarget = IMessenger.Stub.asInterface(target);"这段代码就可以看出,【IMessenger】就是一个具有跨进程能力的AIDL接口。
Messenger的基本用法上我们知道,这里的【IBinder】就是连接服务端时返回来的IBinder,再结合下面这段代码:
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
可以知道Client拿到的【IBinder】其实就是服务端的【Messenger】对象通过【Handler.getIMessenger()】方法返回的【IMessenger】接口
Handler.java关键源码:
class Handler{
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);
}
}
}
从Handler源码可以看到:
- 【Handler.getIMessenger()】方法返回的对象是【MessengerImpl 】
- 【MessengerImpl 】继承自【IMessen.Stub】
- 【MessengerImpl 】的【send(Message msg)】方法实现就是调用当前【Handler】的【sendMessage】方法
所以我们可以看出,【IMessenger】这个AIDL接口功能最终的实现者就是【Handler】,【Handler】通过对外提供【getIMessenger】方法,将自身包装成具有跨进程能力的【IMessenger】AIDL接口,而【Messenger】只是对【IMessenger】接口再一次包装便于使用而已。
小结
Messenger其实就是Handler支持跨进程调用的增强版,调用Messenger的send方法,本质上就是调用远程的Handler的sendMessage方法。