Rxbus 升级为 RxJava 2 版本

之前写了一个简单的Rxbus模块,使用的是RxJava 1.0版本,十月底Rxjava已经更新到了2.0.0,那我就对现有的Rxbus模块做一下升级。

之前Rxbus的连接:
http://www.jianshu.com/writer#/notebooks/3833653/notes/4406055

Step 1

引入最新的RxJava

compile 'io.reactivex.rxjava2:rxjava:2.0.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.0-RC1'

Step 2

修改EventThread.class,删除Schedulers.immediate()相关
因为在2.0中删除了Schedulers.immediate()这个线程的切换

Step 3

修改RxBus.class

Branch 1 CompositeDisposable

old

//存放订阅者信息
 private Map<Object, CompositeSubscription> subscriptions = new HashMap<>();

new

//存放订阅者信息
private Map<Object, CompositeDisposable> subscriptions = new HashMap<>();

CompositeSubscription 修改为 CompositeDisposable
那么自然解除订阅的方式也有了修改
old

CompositeSubscription.unsubscribe();

new

CompositeDisposable.dispose();
Branch 2 Flowable

在2.0中增加了Flowable 这样就把 backpressure 的问题放到了Flowable中来处理,而Observable 不对backpressure进行处理了。

但是使用Flowable还是要注意对backpressure的处理,不然还是会出现以前的问题。

old

Observable.just(subscriber)
                .filter(s -> s != null)//判断订阅者不为空
                .filter(s -> subscriptions.get(subscriber)==null) //判断订阅者没有在序列中
                .map(s -> s.getClass())
                .flatMap(s -> Observable.from(s.getDeclaredMethods()))//获取订阅者方法并且用Observable装载
                .map(m -> {m.setAccessible(true);return m;})//使非public方法可以被invoke,并且关闭安全检查提升反射效率
                .filter(m -> m.isAnnotationPresent(Subscribe.class))//方法必须被Subscribe注解
                .subscribe(m -> {
                    addSubscription(m,subscriber);
                });

new

Flowable.just(subscriber)
                .filter(s -> s != null)//判断订阅者不为空
                .filter(s -> subscriptions.get(subscriber)==null) //判断订阅者没有在序列中
                .map(s -> s.getClass())
                .flatMap(s -> Flowable.fromArray(s.getDeclaredMethods()))//获取订阅者方法并且用Observable装载
                .map(m -> {m.setAccessible(true);return m;})//使非public方法可以被invoke,并且关闭安全检查提升反射效率
                .filter(m -> m.isAnnotationPresent(Subscribe.class))//方法必须被Subscribe注解
                .subscribe(m -> {
                    addSubscription(m,subscriber);
                });

并且要注意.from修改为了.fromArray

Branch 3 Disposable

old

Subscription subscription = tObservable(sub.tag(), cla)

new

Disposable disposable = tObservable(sub.tag(), cla)
Branch 4 元操作符修改

old

/**
     * 订阅事件
     * @return
     */
    public <T> Observable tObservable(int code, final Class<T> eventType) {
        return bus.ofType(Msg.class)//判断接收事件类型
                .filter(new Func1<Msg, Boolean>() {
                    @Override
                    public Boolean call(Msg o) {
                        //过滤code同的事件
                        return o.code == code;
                    }
                })
                .map(new Func1<Msg, Object>() {
                    @Override
                    public Object call(Msg o) {
                        return o.object;
                    }
                })
                .cast(eventType);
    }

new

/**
     * 订阅事件
     * @return
     */
    public <T> Observable tObservable(int code, final Class<T> eventType) {
        return bus.ofType(Msg.class)//判断接收事件类型
                .filter(new Predicate<Msg>() {
                    @Override
                    public boolean test(Msg msg) throws Exception {
                        return msg.code==code;
                    }
                })
                .map(new Function<Msg, Object>() {
                    @Override
                    public Object apply(Msg msg) throws Exception {
                        return msg.object;
                    }
                })
                .cast(eventType);
    }

filter、map在2.0中都有修改,这里只涉及到现在所使用的操作符,其他相关操作符修改请到查看相关 doc

Branch 5 subscribeWith

2.0中新增了subscribeWith()方法,对于这个方法我没有找到过多的解释,这里暂时引用两篇简书中的内容加以说明

subscribe后不再会有 Subscription 也就是如今的 Disposable,为了保持向后的兼容, Flowable 提供了 subscribeWith方法 返回当前的Subscriber对象, 并且同时提供了DefaultSubscriber, ResourceSubscriber,DisposableSubscriber,让他们提供了Disposable接口, 可以完成和以前类似的代码 (引用1)

需要使用subscribeWith而不是subscribe,因为subscribe方法现在返回void (引用2)
因为篇幅有限为避免断章取义,如果对subscribeWith不解请去引用地址查看,引用地址在下方相关连接中。

old

/**
     * 解除订阅者
     * @param subscriber 订阅者
     */
    public void unRegister(Object subscriber) {
        Observable.just(subscriber)
                .filter(s -> s!=null)
                .map(s -> subscriptions.get(s))
                .filter(subs -> subs!=null)
                .subscribe(subs -> {
                    subs.unsubscribe();
                    subscriptions.remove(subscriber);

new

/**
     * 解除订阅者
     * @param subscriber 订阅者
     */
    public void unRegister(Object subscriber) {
        Flowable.just(subscriber)
                .filter(s -> s!=null)
                .map(s -> subscriptions.get(s))
                .filter(subs -> subs!=null)
                .subscribeWith(new Subscriber<CompositeDisposable>() {
                    @Override
                    public void onSubscribe(Subscription s) {

                    }

                    @Override
                    public void onNext(CompositeDisposable compositeDisposable) {
                        compositeDisposable.dispose();
                        subscriptions.remove(subscriber);
                    }

                    @Override
                    public void onError(Throwable t) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

到这里Rxbus的升级就暂时完成了。

问题

在升级过程中也遇到了几个问题,现在暂时还没有解决,也在这里记录一下

1.

SerializedSubject 这个可以吧Subject序列化为线程安全的类没有找到,现在只有SerializedObserverSerializedSubscriber 这两个类,不知道以后是否会增加。

解决
SerializedSubject 已经变为非public类
可以通过bus = PublishSubject.create().toSerialized();的方式获取线程安全 的对象。

2.

在Rxbus解除订阅时我使用了RxJava的写法,如果只改动Observable为Flowable,那么程序会报错。但是在另一段与Retrofit相关的代码中却可以使用。

/**
     * 解除订阅者
     * @param subscriber 订阅者
     */
    public void unRegister(Object subscriber) {
        Observable.just(subscriber)
                .filter(s -> s!=null)
                .map(s -> subscriptions.get(s))
                .filter(subs -> subs!=null)
                .subscribe(subs -> {
                    subs.unsubscribe();
                    subscriptions.remove(subscriber);
APIServiceManager.getInstance()        
.getTravelNotesAPI()        
.getTravelNotesList(key, page + "")        
.compose(RxSchedulersHelper.io_main())        
.compose(SchedulersHelper.handleResult())        
.doOnTerminate(() -> view.disDialog())        
.subscribe(s -> RxBus.getInstance().post(RxBus.TAG_DEFAULT, s.getBookses()),                
e -> RxBus.getInstance().post(RxBus.TAG_ERROR, e.getMessage()));

public interface TravelNotesAPI {    
@GET(APIConfig.BASE_URL_TRAVEL_NOTES+"travellist?")  
Flowable<ResponseJson<TravelNoteBook>>  
getTravelNotesList(@Query("query") String query, @Query("page") String page);}

现在2.0出的时间不长所以如果文章中出现什么问题可以给我留言

相关连接

RxJava 2 :
https://github.com/ReactiveX/RxJava/tree/2.x
RxJava 2 doc:
http://reactivex.io/RxJava/2.x/javadoc/
简书RxJava2说明:
http://www.jianshu.com/p/763322683f23 (引用1)
http://www.jianshu.com/p/850af4f09b61 (引用2)
backpressure相关说明:
http://www.dundunwen.com/article/275b1d92-f9da-4bb8-b111-3aa8a6ace245.html
RxBus:
https://github.com/hackerlc/GearApplication/tree/master/gearlibrary/src/main/java/gear/yc/com/gearlibrary/rxjava/rxbus

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容