All Projects → codyer → Elegantbus

codyer / Elegantbus

Licence: apache-2.0
🔥🔥Android 平台,基于LivaData的EventBus,无侵入,更优雅,支持跨进程,跨应用粘性事件,自定义事件等功能。

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Elegantbus

Unpeek Livedata
LiveData 数据倒灌:别问,问就是不可预期 - Perfect alternative to SingleLiveEvent, supporting multiple observers.
Stars: ✭ 208 (+33.33%)
Mutual labels:  event, eventbus, livedata
azeroth-event
Lightweight event-driven framework
Stars: ✭ 18 (-88.46%)
Mutual labels:  event, eventbus
Bekit
bekit框架致力于解决在应用开发中的公共性痛点,已有“事件总线”、“流程引擎”、“服务引擎”。其中“流程引擎”可作为分布式事务解决方案saga模式的一种实现,并且它很轻量不需要服务端、不需要配置,就可直接使用。
Stars: ✭ 71 (-54.49%)
Mutual labels:  event, eventbus
Liveeventbus
📬EventBus for Android,消息总线,基于LiveData,具有生命周期感知能力,支持Sticky,支持AndroidX,支持跨进程,支持跨APP
Stars: ✭ 3,192 (+1946.15%)
Mutual labels:  eventbus, livedata
evon
Fast and versatile event dispatcher code generator for Golang
Stars: ✭ 15 (-90.38%)
Mutual labels:  event, eventbus
CEventCenter
一个Android事件分发中心库,基于对象池及接口回调实现。实现类似BroadcastReceiver/RxBus/EventBus等的消息事件传递功能,用于在Activity/Fragment/Service之间的消息传递通讯。
Stars: ✭ 116 (-25.64%)
Mutual labels:  event, eventbus
ReactiveBus
🚍 Reactive Event Bus for JVM (1.7+) and Android apps built with RxJava 2
Stars: ✭ 17 (-89.1%)
Mutual labels:  event, eventbus
Multiplatform-Bus
Kotlin event-bus compatible with Android & native iOS
Stars: ✭ 43 (-72.44%)
Mutual labels:  event, eventbus
Channel
一行代码发送和接收事件LiveData|LifeCycle|Coroutine特性的事件总线框架
Stars: ✭ 108 (-30.77%)
Mutual labels:  eventbus, livedata
On Headers
Execute a listener when a response is about to write headers.
Stars: ✭ 131 (-16.03%)
Mutual labels:  event
Kluban
Lifecycle + Kotlin 协程 + flow + LiveData + Glide 识别和内存优化 + Luban采样算法 = KLuban图片压缩
Stars: ✭ 144 (-7.69%)
Mutual labels:  livedata
Android Mvvm Architecture
A basic sample android application to understand MVVM in a very simple way.
Stars: ✭ 129 (-17.31%)
Mutual labels:  livedata
Termux Apt Repo
Script to create Termux apt repositories.
Stars: ✭ 131 (-16.03%)
Mutual labels:  apt
Lapidus
Stream your PostgreSQL, MySQL or MongoDB databases anywhere, fast.
Stars: ✭ 145 (-7.05%)
Mutual labels:  event
Metronome
Metronome is a distributed and fault-tolerant event scheduler
Stars: ✭ 131 (-16.03%)
Mutual labels:  event
Jstarcraft Core
目标是提供一个通用的Java核心编程框架,作为搭建其它框架或者项目的基础. 让相关领域的研发人员能够专注高层设计而不用关注底层实现. 涵盖了缓存,存储,编解码,资源,脚本,监控,通讯,事件,事务9个方面.
Stars: ✭ 150 (-3.85%)
Mutual labels:  event
Androideventbus
[DEPRECATED] A lightweight eventbus library for android, simplifies communication between Activities, Fragments, Threads, Services, etc.
Stars: ✭ 1,597 (+923.72%)
Mutual labels:  eventbus
Androidarchitecture
Android Architecture using Google guides
Stars: ✭ 127 (-18.59%)
Mutual labels:  livedata
Apt Smart
apt-smart: Smart, automated, robust apt-get mirror selection for Debian, Ubuntu and Linux Mint
Stars: ✭ 153 (-1.92%)
Mutual labels:  apt
Ktarmor Mvvm
👻 Android快速开发框架, KtArmor 寓意着 为Android 赋予战斗装甲, 方便开发者快速进行Android 开发。
Stars: ✭ 148 (-5.13%)
Mutual labels:  livedata

ElegantBus

ElegantBus 是一款 Android 平台,基于LivaData的消息总线框架,这是一款非常 优雅 的消息总线框架。

如果对 ElegantBus 的实现过程,以及考虑点感兴趣的可以看看前几节自吹

如果只是想先使用的,可以跳过,直接到跳到使用说明

和常见LivaData实现的EventBus比较

消息总线 使用反射 入侵系统包名 进程内Sticky 跨进程Sticky 跨APP Sticky 事件可配置化 线程分发 消息分组 跨App安全考虑 常驻事件Sticky
LiveEventBus
ElegantBus

来龙去脉

自吹

ElegantBus 支持跨进程,且支持跨应用的多进程,甚至是支持跨进程间的粘性事件,支持事件管理,支持事件分组,支持自定义事件,支持同名事件等。

之所以称之为最优雅的总线,是因为她不仅实现了该有的功能,而且尽量选用最合适,最轻量,最安全的方式去实现所有的细节。 更值得夸赞的是使用方式的优雅!

前言

随着LifeCycle的越来越成熟,基于LifeCycle的LiveData也随之兴起,业内基于LiveData实现的EventBus 也如雨后春笋一般拔地而起。

出于对技术的追求,看过了无数大牛们的实现,各位大神们思路也是出奇的神通,最基础的 LiveData 版 EventBus 其实大同小异,一个单例类管理所有的事件LivaData集合。如果不清楚的可以随便网上找找

反正基本功能 LivaData 都支持了,实现 EventBus 只需要把所有事件管理起来就完事了。

业内基于LiveData实现的EventBus,其实考虑的无非就是下面提到的五个挑战,有的人考虑的少,有的人考虑的多,于是各种方案都有。

ElegantBus 主要是集合各家之优势,进行全方面的考虑而产生的。

五个挑战 之 路途险阻

挑战一 : 粘性事件

  • 背景 LivaData的设计之初是为了数据的获取,因此无论是观察开始之前产生的数据,还是观察开始之后产生的数据,都是用户需要的数据,只要是有数据,当LifeCycle处于激活状态,数据就会传递给观察者。这个我们称之为 粘性数据。 这种设计对于事件来说有时候就不那么友好了,之前的事件用户可能并不关心,只希望收到注册之后发生的事件。

挑战二 : 多线程发送事件可能丢失

  • 背景 同样是因为使用场景的原因,LivaData设计在跨线程时,使用post提交数据,只会保留最后一次数据提交的值,因为作为数据来说,用户只需要关心现在有的数据是什么。

挑战三 : 跨进程事件总线

  • 背景 有时候我们应用需要设置多进程,不同模块可能允许在不同进程中,因为单例模式每个进程都有一份实体,所有无法达到跨进程,这时候设计IP方案选择。

  • 说明 这里提一下为什么不选用广播方式,对广播有一定了解的都知道,全局广播会有信息泄露,信息干扰等问题,而且开销也比较大,因此全局广播并不适合这种情况。 也许有人会说可以用本地广播,然而,本地广播目前来说并不是很好的选择。

Google官方也在 LocalBroadcastManager 的说明里面建议使用LiveData替代: 原文地址

原文如下:

2018 年 12 月 17 日

版本 1.1.0-alpha01 中将弃用 androidx.localbroadcastmanager。

原因

LocalBroadcastManager 是应用级事件总线,在您的应用中使用了层违规行为;任何组件都可以监听来自其他任何组件的事件。 它继承了系统 BroadcastManager 不必要的用例限制;开发者必须使用 Intent,即使对象只存在且始终存在于一个进程中。由于同一原因,它未遵循功能级 BroadcastManager。 这些问题同时出现,会对开发者造成困扰。

替换

您可以将 LocalBroadcastManager 替换为可观察模式的其他实现。合适的选项可能是 LiveData 或被动流,具体取决于您的用例。

更明显的原因是,本地广播好像并不支持跨进程~

挑战四 : 跨应用(权限问题以及粘性问题)

  • 背景 跨进程相对来说还比较好实现,但是有的时候用户会有跨应用的需求,其实这个也是IPC范畴,为什么单独提出来呢? 因为跨应用设计信息安全,权限校验问题,开放给其他应用,但是同时又要兼顾不被非法滥用。 因为数据只是进程内共享的,跨应用时,粘性事件将失效,如果要保持和单进程一样支持粘性事件,需要做特殊处理。

挑战五 : 兼容性,简洁性

  • 背景 一个好的事件总线需要很好的兼容,不同事件应该有个很好的管理,不会造成冲突,事件可以进行多种配置,如某事件是否支持跨进程,是否激活,属于什么分组等等。

使用说明

(一)ElegantBus 接入配置

1、项目级别gradle添加依赖 目前使用的是 jitPack

allprojects {
    repositories {
    ...
    maven { url 'https://jitpack.io' }
}
}

2、在应用 gradle 文件中添加 ElegantBus 最新版本依赖

def version = "2.0.0"
dependencies {
    implementation "com.github.codyer.ElegantBus:core:$version" // 不需要跨进程时使用
//  implementation "com.github.codyer.ElegantBus:ipc-aidl:$version" // 跨进程时使用(方式1:aidl 实现,已经包含 core)
//  implementation "com.github.codyer.ElegantBus:ipc-messenger:$version" // 跨进程时使用(方式2:messenger 实现,已经包含 core)
//	annotationProcessor "com.github.codyer.ElegantBus:compiler:$version"// 需要事件自动管理时使用
}
如果不需要跨进程,以上两步配置就可以了,如果需要跨进程,第二步选择一个跨进程的方式,并添加第三步配置,且设置第四步。

3、在应用 gradle 文件中的 manifestPlaceholders 配置是否支持跨 App,以及主 App 的 applicationId

manifestPlaceholders = [
    BUS_SUPPORT_MULTI_APP  : true,// 是否支持跨App
    BUS_MAIN_APPLICATION_ID: "com.example.bus" // 肯定会被安装的主app的applicationId
]

为了App安全性,必须使用相同的密钥签名的App才可以设置为一个公用组,否则Debug模式下会抛出异常,Release模式下会输出 error 信息。

4、分别在应用的 Application 的 onCreate 和 onTerminate 方法中添加开始支持多进程和结束多进程

public class BusApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        ElegantBus.setDebug(true);// 可以打开日志开关
        ElegantBusX.supportMultiProcess(this);
    }

    @Override
    public void onTerminate() {
        ElegantBusX.stopSupportMultiProcess();
        super.onTerminate();
    }
}
以上几步就完成了使用 ElegantBus 的全部配置,下面进入使用环节

(二)ElegantBus 使用说明

1、 发送事件

最简单方式就是直接一句

ElegantBus.getDefault("EventA").post(new Object());
ElegantBus.getDefault("EventA").post("eventA");
ElegantBus.getDefault("EventA").post(888888);

可以在任何线程发送都是OK的,考虑大部分是没有跨进程需求的,所以这里默认,这种最简单的方式,这个事件 EventA 是不支持跨进程的。 如果要进行跨进程可以使用重载函数进行设置,重载函数如下:

ElegantBus.getDefault(String group, String event, Class<T> type, boolean multiProcess);
以下说的激活状态指页面处于RESUMED情况

2、 接收事件

接收事件也很简单:

  • 常规事件

生命周期相关的事件,只有页面处于激活状态才会收到事件,如果在页面非激活状态时有事件发生,等页面激活(OnResume)时会收到事件。

ElegantBus.getDefault("EventA").observe(this, new ObserverWrapper<Object>() {
            @Override
            public void onChanged(final Object value) {
                ElegantLog.d(value.toString());
            }
        });
  • 粘性事件

如果观察之前有事件发生,也可以收到事件,eg:A页面发送事件,打开B页面,B页面开始观察,用粘性事件也可以收到。

ElegantBus.getDefault("EventA").observeSticky(this, new ObserverWrapper<Object>() {
            @Override
            public void onChanged(final Object value) {
                ElegantLog.d(value.toString());
            }
        });
  • 常驻事件

和生命周期无关,无论页面是否在激活状态,都可以收到事件,前提是页面已经打开了。

ObserverWrapper<Object> foreverObserverWrapper;
ElegantBus.getDefault("EventA").observeForever(foreverObserverWrapper = new ObserverWrapper<Object>() {
            @Override
            public void onChanged(final Object value) {
                ElegantLog.d(value.toString());
            }
        });
// 常驻事件要自己取消注册,避免内存泄露
ElegantBus.getDefault("EventA").removeObserver(foreverObserverWrapper);
  • 其实普通事件和常驻事件都支持粘性事件

只要创建 ObserverWrapper 时设置 sticky = true 就可以; ElegantBus 提供了默认构造函数如下:参数true 表示粘性事件

new ObserverWrapper<Object>(true) {
		@Override
		public void onChanged(Object value) {}
   })
以上简单的使用就介绍完毕了

高级特性

  • 可以发现,上面的方式,接收的数据类型是 Object 的,因此,只要是同名的事件,无论发送的是什么类型,观察者都可以接收到。 为了对事件进行统一管理,防止事件冲突,事件大小写等拼写错误带来的问题,个人不建议直接使用这种方式

推荐使用事件定义方式

事件定义

  • 先上例子
@EventGroup(value = "TestScope", active = true)
public class EventDefine {
    @Event(description = "eventInt 事件测试", multiProcess = false, active = true)
    Integer eventInt;

    @Event(description = "eventString 事件测试", multiProcess = true, active = true)
    String eventString;

    @Event(description = "eventBean 事件测试", multiProcess = true, active = true)
    JavaBean eventBean;
}
说明

其实事件定义只用到两个注解

1)、@EventGroup 使用在 class 上,定义事件分组名是否激活

2)、@Event 使用在变量上,定义具体 事件描述是否激活是否支持多进程

定义完注解后,通过前面导入的注解处理器 annotationProcessor ,ElegantBus 会自动生成以 EventGroup 定义的分组名的事件总线 例如上面的定义就会生成一个 TestScopeBus

然后我们所有地方就可以直接使用这个事件总线进行事件管理。

  • 发送事件
TestScopeBus.eventInt().post(888);
TestScopeBus.eventString().post("新字符串");
TestScopeBus.eventBean().post(new JavaBean());
  • 接收事件
TestScopeBus.eventInt().observe(owner, new ObserverWrapper<Integer>() {
	@Override
	public void onChanged(final Integer value) {
		...
	}
});

事件回调在非UI线程执行

默认事件是在主线程回调的,如果想在非主线程回调,设置 ObserverWrapper.uiTread = false,同时提供默认构造函数设置是否在UI线程回调。

欢迎 Star 和提交 Issue

  • 为了 ElegantBus 更好的为大家提供服务,更好的兼容性,我特意做了很多场景的测试,可能会有覆盖不到的,如果遇到问题,欢迎留言评论

  • 测试项目地址: ElegantBus-example

  • 老版本请查看分支 v1.0.0 老版本说明

  • 更详细说明

如果想了解更多设计细节,可以参考简书上的说明: 如何优雅的使用LiveData实现一套EventBus(事件总线)

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].