Android框架式编程之HermesEventBus框架

在《Android框架式编程之EventBus》  和 《Android 开发框架 EventBus 原理解析》  中,明确了如何使用EventBus作为事件总线,简化Android各个组件的通信复杂度,并了解了其实现原理。但是EventBus只限于同一个进程中,如果想要在多个进程之间也能像EventBus一样这样使用,此时可以借用饿了么开源的HermesEventBus这个框架。

一、HermesEventBus 框架介绍

HermesEventBus 框架仓库地址:https://github.com/Xiaofei-it/HermesEventBus

HermesEventBus 拥有 EventBus 全部的作用和相同的 API (内部依赖EventBus) ,其主要作用就是基于 EventBus 实现的进程间通信,这个框架基于两个库开发:HermesEventBus。事件收发是基于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。 有时间的可以进行学习了解,扩宽自己的思路,实际生产环境使用不推荐。】

 

posted @ 2020-11-27 17:32  灰色飘零  阅读(1290)  评论(0编辑  收藏  举报