一、什么是Hermes?
Hermes是饿了么提供的一个开源框架,实现跨进程通信。
它不需要通过aidl实现跨进程。
二、如何使用Hermes?
有个小需求:A进程有个单例UserManager,里面能对内部的成员变量name赋值,现在A进程赋值name这个变量后,在B进程需要拿到name赋值后的结果。怎么实现呢?
上一篇我们知道两个进程之间的内存区域是不一样的,虽然B进程能拿到A进程的单例对象,但是两个单例对象名字相同,但是本质不同,所以无法进行数据上的交互。这时就需要有个代理的接口IUserManager,通过注解@ClassId的方式,将IUserManager与UserManager一一对应起来:
image.png
A进程的MainActivity里面先初始化Hermes,然后调用单例类UserManager的赋值方法:
image.png
B进程的SecondActivity先连接Hermes服务,再获取IUserManager接口,接口的getName方法,就是A进程UserManager的getName方法,通过注解产生一一对应的关系
image.png
另外不要忘记注册Hermes的服务:
image.png
三、Hermes架构分析及手写实现
我先给大家总结一下通信的难点所在:
image.png
1.如何实现子线程与主线程之间的交互通信?
2.如何实现跨进程之间的通信?
3.使用Hermes架构为何不用我们再次新增加AIDL文件?
第一点我们在上一篇文章已经说明了怎么解决子线程与主线程之间的交互通信,现在回答第二点,Android跨进程通信必须要通过AIDL定义的接口再结合Binder机制实现,所以EventBus想要实现跨进程,就必须增加AIDL文件,那么Hermes就是基于EventBus的底层封装。再回到第三点,Hermes其实内部定义了Request.aidl和Responce.aidl两个最基本的请求和返回的aidl,另外再定义了一个EventBusService.aidl,它结合了前两个aidl,将所有请求用Request这个基类表示,再将所有返回用Responce这个基类表示。
好了,接下来又会面临另外个棘手的问题:我们自定义的普通数据类怎么让它跨进程呢?此时Hermes内部是将需要跨进程的类,拆分成Json格式的字符串,将跨进程的类名、执行的方法、方法的返回接口、方法的参数这些全都用String来表示,然后拼接成JsonString的格式,来实现跨进程传输,传输成功后,再另外的进程再次解析参数,找到对应的类,执行对应的方法。这就是大体的流程。
思维导图:
最后,B进程通过Binder拿到了A进程执行的返回结果Responce,那么还要不要再通过反射获得UserManager这个对象呢?肯定不需要,因为B进程压根就不知道UserManager这个类,它只是知道有IUserManager这个接口,那么B进程怎么调用A进程的UserManager里面的方法呢?这里用到了动态代理,让B进程误以为它拿到了A进程的真实对象,其实这一切都是代理类提供的假象:
image.png
所以说代理设计模式在架构中用的很广泛,同学们需要掌握。
Demo地址:
https://github.com/cWX411904/MyEventBus
网友评论