Messenger 的工作原理

(写在开头:本文转自liwenkun,觉得文章写得很好故转载到简书,原始文章链接已在下面贴出,感谢作者的无私奉献,如有侵权或者其他问题,请及时联系本人)
原文作者信息:

作者:liwenkun
原文:http://liwenkun.me/2017/02/25/how-does-messenger-work/
版权声明:本文为博主原创文章,转载请附上博文链接!

Messenger 的工作原理

我们知道,Handler 是安卓用来进行线程间通信的工具,但是如果涉及到进程间通信呢,可以用 Handler 吗?答案是否定的。因为 Handler 实现的线程共享是基于统一进程的线程共享同一进程空间这一事实的。而不同进程拥有不同的进程空间,所以 Hander 机制不能于进程间通信。别太沮丧,安卓为我们提供了一个 Handler 的变体让我们可以通过和 Handler 类似的方式实现进程间通信,它就是 Messenger

IMessenger

我们知道进程间通信如果是通过 Binder 实现的,Messenger 也不例外。既然如此,那么一定会有 Binder 接口作为服务端和客户端的通信契约(类似于 AIDL 接口),在这里这个接口就是 IMessenger。它的定义如下:

对于这个接口,需要有服务端的实现和客户端的实现。其中服务端的实现就“藏”在 Handler 中,它是 Handler 的内部类:

关于 Stub 类是什么,在安卓进程通信机制之 AIDL已经解释过了,它是一个继承自 Binder 的抽象类,内部封装了 Binder 通信机制,同时它还实现了 IMessenger 接口,但是它自己并没有真正意义的实现,而是留给服务端去实现,这里也就是 MessengerImplMessengerImpl 实现这个接口的方式就是简单地把发送来的消息转发给外部类 Handler,由 Handler 投递给消息队列。

Messenger

既然我们说 MessengerHandler 的变体,那么我们自然的会认为 Messenger 应该具有这样的功能,或者说使用方法:在客户端进程中投送一个消息给服务端,服务端通过解析这个消息的内容执行相应的动作。那么,Messenger 是怎样做到的呢?它和 IMessengerMessengerImpl 又有什么关联?首先我们从它的构造方法看起:

其中 mTarget 是一个 IMessenger 对象;而 target.getIMessenger() 就是前面的 MessengerImpl 对象。从这里我们很容易发现通过第一个构造方法构造的 MessengermTargetBinder 接口在服务端的实现;而第二个构造方法构造出的 MessengermTargetBinder 接口在客户端的实现(不懂的话可以看看我的这篇文章)。

现在我们对 Messenger 有了一个具体的认知:为了给开发者提供最简单的接口,系统又在 IMessenger 的基础之上用 Messenger 又封装了一层,将 Binder “隐藏”起来。我们通过 Messenger 的使用示例来说明:

首先定义服务端,我们在 Service 中实现:

然后是客户端的实现,我们放在 Activity 中:

这样就通过 Messenger 实现了进程间的通信,这和我们用 Handler 实现线程间通信非常相似。Messenger 在服务端和客户端都有使用,但是使用的构造方法不一样,这也正和前面的分析一致。用一张图来说明 Messenger 的工作原理:

《Messenger 的工作原理》 image

对于这张图说明如下:

  • 实现了客户端消息到服务端的传递。
  • 整个过程的实质是两端的 mTarget 通过 Binder 通信,其他对象只是起辅助作用。
    原文作者:侠和洛
    原文地址: https://www.jianshu.com/p/20be9398e752
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞