Android框架式编程之HermesEventBus框架
在《Android框架式编程之EventBus》 和 《Android 开发框架 EventBus 原理解析》 中,明确了如何使用EventBus作为事件总线,简化Android各个组件的通信复杂度,并了解了其实现原理。但是EventBus只限于同一个进程中,如果想要在多个进程之间也能像EventBus一样这样使用,此时可以借用饿了么开源的HermesEventBus这个框架。
一、HermesEventBus 框架介绍
HermesEventBus 框架仓库地址:https://github.com/Xiaofei-it/HermesEventBus。
HermesEventBus 拥有 EventBus 全部的作用和相同的 API (内部依赖EventBus) ,其主要作用就是基于 EventBus 实现的进程间通信,这个框架基于两个库开发:Hermes和EventBus。事件收发是基于EventBus,IPC通信是基于Hermes。
二、HermesEventBus 实现跨进程通信的原理
Hermes是一个简单易用的Android IPC库。HermesEventBus 先选一个进程作为主进程,将其他进程作为子进程。每次一个event被发送都会经过以下四步:
1、使用Hermes库将event传递给主进程。
2、主进程使用EventBus在主进程内部发送event。
3、主进程使用Hermes库将event传递给所有的子进程。
4、每个子进程使用EventBus在子进程内部发送event。
其实现方案的原理图如下:
通过这种方式,能实现在单一进程内进行多进程开发,也可以实现跨App实现Event事件收发。
三、HermesEventBus 使用方式
1. 单一App内使用HermesEventBus的方式
在单一app内进行多进程开发,那么只需要做以下三步:
首先,在gradle文件中加入下面的依赖:
dependencies { compile 'xiaofei.library:hermes-eventbus:0.3.0' }
然后,在Application的onCreate中加上以下语句进行初始化:
HermesEventBus.getDefault().init(this);
最后,在每次使用EventBus的时候,用HermesEventBus代替EventBus。
HermesEventBus.getDefault().register(this); HermesEventBus.getDefault().post(new Event());
HermesEventBus也能够在一个进程间传递event,所以如果你已经使用了HermesEventBus,那么就不要再使用EventBus了。
当进程不需要再发送和接受event的时候,那么这个进程必须调用:
HermesEventBus.getDefault().destroy();
否则你会收到android.os.DeadObjectException
和其他一些异常。这些异常会打印一些异常信息但不会导致app崩溃。
2. 多个App内使用HermesEventBus的方式
如果你想在多个app间收发event,那么就做如下几步:
首先,在每个app的gradle文件中加入依赖:
dependencies { compile 'xiaofei.library:hermes-eventbus:0.3.0' }
然后,选择一个app作为主app。你可以选择任意app作为主app,但最好选择那个存活时间最长的app。
在主app的AndroidManifest.xml中加入下面的service:
<service android:name="xiaofei.library.hermes.HermesService$HermesService0"/>
你可以加上一些属性。在app间收发的事件类必须有相同的包名、相同的类名和相同的方法。务必记住在代码混淆的时候将这些类keep!
然后在主app的application类的onCreate方法中加入:
HermesEventBus.getDefault().init(this);
其他app的Application类的onCreate方法中加入:
HermesEventBus.getDefault().connectApp(this, packageName);
“packageName”指的是主app的包名。
同上一样,在每次使用EventBus的时候,用HermesEventBus代替EventBus。
HermesEventBus.getDefault().register(this); HermesEventBus.getDefault().post(new Event());
HermesEventBus也能够在一个进程间传递event,所以如果你已经使用了HermesEventBus,那么就不要再使用EventBus了。
如果进程不需要再发送和接受event,那么这个进程必须调用:
HermesEventBus.getDefault().destroy();
否则你会收到android.os.DeadObjectException
和其他一些异常。这些异常会打印一些异常信息但不会导致app崩溃。
参考:https://github.com/Xiaofei-it/HermesEventBus/blob/master/README-zh-CN.md
至此HermesEventBus的基本使用就够了,但是学习知识,我们必须要知其然,知其所以然。因为这个项目目前也是很久没维护了,如果我们想尝试商用,还是需要了解其原理并在以后能够尽量维护和完善这套框架的。
四、HermesEventBus 的原理
在Application中进行了初始化操作:
HermesEventBus.getDefault().init(this);
当主进程和子进程创建的时候,都会执行此方法,在init方法内部,对主进程和子进程的初始化调用分别执行了不同的逻辑:
public void init(Context context) { mContext = context.getApplicationContext(); mMainProcess = isMainProcess(context.getApplicationContext()); if (mMainProcess) { Hermes.init(context); Hermes.register(MainService.class); mMainApis = MainService.getInstance(); Log.e(GlobalConfig.Log_TAG, "Main ProcessInit"); } else { mState = STATE_CONNECTING; Hermes.setHermesListener(new HermesListener()); Hermes.connect(context, Service.class); Hermes.register(SubService.class); Log.e(GlobalConfig.Log_TAG, "Child ProcessInit"); } }
五、Hermes 进阶整理
Hermes 手写实现核心逻辑:https://gitee.com/renhui112115/hermes-event-bus
附(优秀开源IPC框架) :
Hermes : https://github.com/Xiaofei-it/Hermes:Hermes的原理是利用动态代理+反射的方式来替换AIDL生成的静态代理。
Andromeda:https://github.com/iqiyi/Andromeda。爱奇艺开源的IPC框架,加入了跨进程通信的事件总线,加入了对增强进程稳定性的考量,通过为各个进程预先插桩Service,在获取远程服务时用前台UI组件(Activity/Fragment/View)绑定插桩的Service,最终提升后台服务进程优先级。支持IPCCallback。支持配置Binder分发管理中心(Dispatcher)所属进程。【2021年1月补充:Andromeda 框架现阶段存在Gradle插件使用问题:Caused by: groovy.lang.MissingPropertyException: No such property: absolutePath for class: org.gradle.api.internal.file.DefaultFilePropertyFactory$DefaultDirectoryVar。 有时间的可以进行学习了解,扩宽自己的思路,实际生产环境使用不推荐。】