简单封装RxBus

简单封装Rxbus

在组件化的工程中,不同组件通常位于不同的模块中,实现组件间的通信有多种方案,最常用的是Eventbus,但是如果项目中有使用Rxjava的话,我们可以使用RxJava的响应式编程替换掉Eventbus,接下来我们将逐步探索RxBus的封装。

1. 单一的订阅关系

首先看一种封装,如下:

public enum RxBus {

    INSTANCE;

    // 发射器
    private ObservableEmitter mEmitter;

    private Observable mObservable = Observable.create (emitter -> {
           mEmitter = emitter;
           emitter.onNext (new Object ());
        });

    public void post(Object obj){
        mEmitter.onNext (obj);
    }

    public <T> Observable<T> toObservable(Class<T> clazz){
        // 只处理clazz类型的数据
        return mObservable.ofType (clazz);
    }
}

使用方法如下:
事件发送方:

            ModuleAEvent event = new ModuleAEvent ();
            event.setName ("hello");
            RxBus.INSTANCE.post (event);

接收方:

RxBus.INSTANCE.toObservable (ModuleAEvent.class).subscribe (
                moduleAEvent -> {
                    Log.d (TAG, "ModuleAEvent name is: " + moduleAEvent.getName ());
                },
                throwable -> {
                    Log.d (TAG, "error!");
                }
        );

ModuleAEvent为定义的事件类型,一个简单的javabean:

public class ModuleAEvent {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

由于是全局使用的,所以使用一个枚举单例。如果使用,会发现这种方式只能支持一个订阅者,也就是一个组件发出的事件只能被一个组件接收,不支持多个组件订阅同一个事件。显然这不能满足要求,我们需要寻找更好的方法。

2. 多个订阅者

查看RxJava的文档可以发现一个名为Subject的抽象类,它的描述如下:
在这里插入图片描述
注释明确指出了允许单一事件源向多个观察者发送多个事件(我理解的这里的多个事件指的是多个onNext()方法的执行), 开来这就是要找的类了。这是一个抽象类,他有多个实现:
在这里插入图片描述
所有的子类都对外隐藏了构造方法,但是提供了一个create()静态方法拿到相应的实例。所以我们用其中任意一个公开的类拿到实例,进而封装RxBus,比如我选用了PublishSubject这个子类,那么我的RxBus可以这样封装:

public enum RxBus {
    INSTANCE;

    private Subject mSubject = PublishSubject.create ();

    public void post(Object obj){
        mSubject.onNext (obj);
    }

    public <T> Observable<T> toObservable(Class<T> clazz){
        // 只处理clazz类型的数据
        return mSubject.ofType (clazz);
    }
}

测试后发现一个事件确实可以被多个订阅者同时订阅。

3. 粘性事件的支持

粘性事件指的是订阅者在事件发出之后才和事件建立订阅关系,有时我们同样希望这些事件不被错过,所以这些事件应该在建立订阅关系的时候发送给订阅者,这个就是粘性事件。上面封装的RxBus是不能满足这种需要的,如何更改呢?
其实Subject的几个实现类中有一个子类ReplaySubject。查看文档会发现:
在这里插入图片描述
向现在和以后的订阅者回应事件,显然就是这个了,下面的示例也证实了这一点:
在这里插入图片描述
所以,支持粘性事件的RxBus封装如下:

public enum RxBus {
    INSTANCE;

    private Subject mSubject = ReplaySubject.create ();

    public void post(Object obj){
        mSubject.onNext (obj);
    }

    public <T> Observable<T> toObservable(Class<T> clazz){
        // 只处理clazz类型的数据
        return mSubject.ofType (clazz);
    }
}

这里只是简单的实现了功能,更多的细节,比如数据流的及时断开等,可以根据具体的应用场景再进一步封装。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值