这个 RxBus 稳如老狗

作者: Blankj | 来源:发表于2018-05-09 11:29 被阅读782次
logologo

![rb][rbsvg] ![License][licensesvg]

Download

Gradle:

implementation "com.blankj:rxbus:1.1"

How to use

非粘性事件

  1. 注册事件
public class YourActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 注册 String 类型事件
        RxBus.getDefault().subscribe(this, new RxBus.Callback<String>() {
            @Override
            public void onEvent(String s) {
                Log.e("eventTag", s);
            }
        });

        // 注册带 tag 为 "my tag" 的 String 类型事件
        RxBus.getDefault().subscribe(this, "my tag", new RxBus.Callback<String>() {
            @Override
            public void onEvent(String s) {
                Log.e("eventTag", s);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销
        RxBus.getDefault().unregister(this);
    }
}
  1. 发送事件
// 发送 String 类型事件
RxBus.getDefault().post("without tag");

// 发送带 tag 为 "my tag" 的 String 类型事件
RxBus.getDefault().post("with tag", "my tag");

粘性事件(也就是先发送事件,在之后注册的时候便会收到之前发送的事件)

  1. 发送事件
// 发送 String 类型的粘性事件
RxBus.getDefault().postSticky("without tag");

// 发送带 tag 为 "my tag" 的 String 类型的粘性事件
RxBus.getDefault().postSticky("with tag", "my tag");
  1. 注册事件
public class YourActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 注册 String 类型事件
        RxBus.getDefault().subscribeSticky(this, new RxBus.Callback<String>() {
            @Override
            public void onEvent(String s) {
                Log.e("eventTag", s);
            }
        });

        // 注册带 tag 为 "my tag" 的 String 类型事件
        RxBus.getDefault().subscribeSticky(this, "my tag", new RxBus.Callback<String>() {
            @Override
            public void onEvent(String s) {
                Log.e("eventTag", s);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销
        RxBus.getDefault().unregister(this);
    }
}

Nice wrap

如果用到事件总线的地方比较多,那么可以把事件总线的使用放到一个 Manager 中使用,比如我 Demo 中做的封装如下所示:

public class RxBusManager {

    private static final String MY_TAG = "MY_TAG";

    public static void subscribeRxBusManagerActivity(final RxBusManagerActivity activity){
        RxBus.getDefault().subscribe(activity, new RxBus.Callback<String>() {
            @Override
            public void onEvent(String s) {
                activity.updateText("without " + s);
            }
        });

        RxBus.getDefault().subscribe(activity, MY_TAG, new RxBus.Callback<String>() {
            @Override
            public void onEvent(String s) {
                activity.updateText("with " + s);
            }
        });
    }

    public static void postToRxBusManagerActivity(final String event) {
        RxBus.getDefault().post(event);
    }

    public static void postWithMyTagToRxBusManagerActivity(final String event) {
        RxBus.getDefault().post(event, MY_TAG);
    }

    public static void postStickyToRxBusManagerActivity(final String event) {
        RxBus.getDefault().postSticky(event);
    }

    public static void postStickyWithMyTagToRxBusManagerActivity(final String event) {
        RxBus.getDefault().postSticky(event, MY_TAG);
    }

    public static void unregisterRxBusManagerActivity(final RxBusManagerActivity activity) {
        RxBus.getDefault().unregister(activity);
    }
}

可以看出这是在 RxBusManagerActivity 中要使用 RxBus 的相关代码,这样可以更方便地管理应用中所有的事件总线,而不至于发了个事件都不清楚接收方在哪的尴尬。

How it comes

网上现有 RxBus 存有的问题:

  1. 使用的 RxBus 大多停留在 RxJava1 版本
  2. RxBus 实现的粘性事件很多都是有问题的
  3. 如果事件抛了异常,之后便再也无法接收到的问题
  4. 同类型事件需自己再次封装 Bean 进行区别。

介于以上问题,我还是亲自封装一个简洁的供大家使用,库已经依赖了 RxAndroid 和 RxJava,所以导入了该库的就不需要再额外导入那两库了。

当然,如果通信频率比较高追求效率的话还是推荐使用 EventBus

Principle

  1. 利用 FlowableProcessor 既可以作为观察者又可以作为被观察者来实现事件总线
  2. 粘性事件原理就是发送的时候把事件存到一个 hash 表中,在注册的时候查询下 hash 表中是否存在符合的事件,有的话就消费掉即可
  3. 替换原有 LambdaSubscriber 来让抛了异常之后可以继续接收到后续事件
  4. 封装了 TagMessage 来区分不同类别的 tag
  5. 动态识别范型对象来省去传入 Type 类型

还有一些细节就自己看源码去了解吧,总共有用的代码不超过 300 行哈。

Change log

如果正好帮到了你,那可真是巧了哈,欢迎来我的 狗窝 坐坐。

相关文章

  • 这个 RxBus 稳如老狗

    ![rb][rbsvg] ![License][licensesvg] Download Gradle: How ...

  • 稳如老狗

    (1)各位看官,大家好,老狗不食筷上肉。 作为一条老狗,我有必要向大家介绍一下我的团队成员。 我们团队一共四狗。除...

  • 稳如老狗

    一个戴着眼镜、身高七尺的大叔,看见一个非常漂亮的小树,已经长上了叶子,三尺高。突然萌生一动作在了树下。一个管理员拿...

  • 看似稳如老狗

    其实心里慌得一匹

  • 稳如老狗的人

    人的一生在不停的做着选择题,选项只能有一个,但是却没有对错,思前顾后的人会对每个选项进行细细的分析,是那种极度...

  • 看似稳如老狗

    可能因为最近种种的缘故,我感觉情志不畅有点肝郁气滞。突然感觉事情跟我想象的完全不一样,不是说好了上课打王者,下课打...

  • 2018-06-14

    有点心慌,我也想成为那种稳如老狗的存在

  • 稳如老狗 - 调试工具Charles

    Charles 是很棒棒的跨平台代理调试工具, 能帮助你快速的定位网络问题 介绍 Charles 提供了很多很强大...

  • 股市红彤彤,而我稳如老狗

    最近一段时间,股市一片红彤彤,而我买基金赚的钱依旧稳如老狗。 虽说买股票容易赚大钱,但也容易亏钱,...

  • 2019-02-02

    只有小孩才哭哭咧咧 成年人应该稳如老狗 可又说小孩天真无邪 幼稚形容成年人多些

网友评论

  • _Cancer:狗窝真不错:joy:
  • 过期的薯条:不错 为大佬点赞
  • 浮华染流年:感觉还是不要用rxbus来做消息传递,需要传递的时候直接暴露一个obserable就可以了消息直接到达目的地
  • EveMemo:其实我感觉rx对应eventbus的提升不大。如果是老项目完全没必要升级,作为一个了解就可以了。新项目可以考虑吧rxbus引入项目中
    EveMemo:@Blankj 嗯嗯。可以做个rxjava的学习项目。:wink:
    Blankj:@EveMemo 老项目当然不要折腾了,新项目可以考虑使用,普通应用在考虑效率方面基本没有差异,只有在高频通讯比如一秒钟几百次的这种事件才需要考虑使用效率更高的,所以,最终的选择就是选择简单易用的即可,我这个也就是 RxJava 的拓展而已

本文标题:这个 RxBus 稳如老狗

本文链接:https://www.haomeiwen.com/subject/eqsnrftx.html