IBinder 是个接口,而Binder是他的实现类,binder的底层实现由驱动程序陷入内核的,大体是进程A将信息给binder从陷入内核,而后再由内核的驱动程序发给进程B,大体是这样具体我也不太清楚。
Binder真正起作用的是onTrancat()
和 Trancat()
函数这两个函数主要实现了进程间的信息传递,AIDL大体流程是通过binder告诉另外一个进程我想要执行什么函数,并且把参数传递过去,然后再由binder将执行结果传递会来,主要是binder的跨进程传递信息。
而Messenger则是在AIDL的基础上再做了一层封装,通过AIDL的远程函数调用将Message发给远程的Handler处理。
Messenger实现细节
Messenger有两个构造函数
Messenger(Handler target)
Messenger(IBinder target)
Handler中的IMessage是一个AIDL借口服务端调用第一个构造函数让Messenger持有Handler中的AIDL借口,然后将IBinder对象给远程调用端用来调用第二个构造函数。在第二个构造函数中会调用asIIterface()函数就和普通的AIDL借口是一样的。
那为什么从replyto中穿过来的Messenger可以直接用来从服务器端和客户端通信呢?
主要是因为客户端序列化的时候写入Parcel的是Messenger的IBinder,而反序列话的时候是从Parcel中读出了IBinder然后调用了第二个构造Handler函数构造了Messenger,实际上和服务器端返回IBinder然后客户端构造Messenger是一样的过程,只是这个过程隐藏在序列化和反序列化中。
补充
- Messenger类没有实现实际功能,这个类类似一个代理类,执行了一些繁琐的细节,真正实现的是Handler中的AIDL接口IMessenger
IMessenger mMessenger;
这个mMessenger还采用了lazy loading的写法,synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
// mMessenger 为空则重新创建
mMessenger = new MessengerImpl();
return mMessenger;
}
getImessenger函数也是直接粗暴的写出来了,没用什么双重检查一类的。可能是因为这个函数调用比较少吧 private final class MessengerImpl extends IMessenger.Stub
这个Messenger其实是Handler的内部类,这样就可以直接调用send方法,而且封装比较好,类似于系统根据AIDL生成的binder类,整个套在一接口中。