2章 RxJava基本使用

本篇文章已授权微信公众号 YYGeeker 独家发布转载请标明出处

CSDN学院课程地址

2. RxJava基本使用

在RxJava使用之前记得在Gradle中添加依赖引入

implementation "io.reactivex.rxjava2:rxjava:2.1.12"
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'

2.1 事件发射

在上面的例子中,我们可以注意到被观察者中有个Emitter(发射器),发射器的位置位于subscribe回调参数ObservableEmitter<String> e中,通过名字我们可以知道,RxJava的事件通知就是通过它来进行发送的,所以它是一个事件发射器,发射器能发送的事件有onNext()onComplete()onError(),在观察者的回调中,分别对应着相同方法名进行回调,这里对观察者的回调方法进行简单介绍

  • onSubscribe():当观察者被订阅时回调
  • onNext():当观察者收到onNext事件时回调
  • onComplete():当观察者收到onComplete事件时回调
  • onError():当观察者收到onError事件时回调

2.2 链式调用

人类就喜欢酷炫的东西,炫耀自身的优点,当然RxJava也少不了人类这种心理,就是链式编程,下面这段代码可以完美替代例子上面的所有代码,其效果是和上面一样的。这里需要注意的是,创建Observer过程中,会将所有的接收方法都创建出来,如果此时程序发生异常,RxJava默认会将异常信息try-catch

public static void main(String[] args) {
    //创建被观察者
    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        //默认在主线程里执行该方法
        public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
            e.onNext("俊俊俊很帅");
            e.onNext("你值得拥有");
            e.onNext("取消关注");
            e.onNext("但还是要保持微笑");
            e.onComplete();
        }
    })
            //创建观察者并订阅
            .subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(String s) {
                    System.out.println("onNext=" + s);
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
}

2.3 选择调用

久而久之,人类喜欢简洁,喜欢定制服务,巧了,RxJava也给你满足了,下面这段代码中,实现的方法跟上面的实现方法是对应起来的,大家看参数就知道哪个对应哪个了,你可以通过创建Consumer,不需要实现的方法你可以不写,看上去更简洁,这里我为了方便大家看,都new出来了,Consumer就是消费者的意思,可以理解为消费了onNext等等等事件。这里需要注意的是,创建Consumer过程中,如果没有将第二个Throwable的Consumer创建出来,如果此时程序发生异常,程序将会崩溃

public static void main(String[] args) {
    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
            e.onNext("俊俊俊很帅");
            e.onNext("你值得拥有");
            e.onNext("取消关注");
            e.onNext("但还是要保持微笑");
            e.onComplete();
        }
    }).subscribe(
            new Consumer<String>() {
                @Override
                public void accept(@NonNull String s) throws Exception {
                    //对应onNext()
                    System.out.println("accept=" + s);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(@NonNull Throwable throwable) throws Exception {
                    //对应onError()
                }
            }, new Action() {
                @Override
                public void run() throws Exception {
                    //对应onComplete()
                }
            }, new Consumer<Disposable>() {
                @Override
                public void accept(@NonNull Disposable disposable) throws Exception {
                    //对应onSubscribe()
                }
            });
}

2.4 线程切换

当然Rxjava的使用不仅仅这么简单的事件发送,他还能完成一些业务上的逻辑。比如注册登录操作,正常的逻辑是通过注册去获取用户的Token,然后通过Token进行登录,这个过程涉及到注册需要在子线程去进行网络请求,然后在UI线程中更新界面提示,然后再切换到子线程进行登录操作,最后又得切换到UI线程去更新界面,这一系列的操作,也是可以通过RxJava的线程切换来进行实现,在RxJava中的线程切换特别简单,只要下面这两句话就能自由的在子线程和UI线程中自由切换

public static void main(String[] args) {
    //创建被观察者
    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        //默认在主线程里执行该方法
        public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
            e.onNext("俊俊俊很帅");
            e.onNext("你值得拥有");
            e.onNext("取消关注");
            e.onNext("但还是要保持微笑");
            e.onComplete();
        }
    })
            //将被观察者切换到子线程
            .subscribeOn(Schedulers.io())
            //将观察者切换到主线程  需要在Android环境下运行
            .observeOn(AndroidSchedulers.mainThread())
            //创建观察者并订阅
            .subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(String s) {
                    System.out.println("onNext=" + s);
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
}

2.5 线程调度器

说到线程切换,就必须不得不说的是RxJava的线程调度器,其调度器就是Schedulers,在调度器中封装了各式各样的线程提供给我们使用,下面举例其现有的调度器列表

调度器类型 效果
Schedulers.computation() 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量
Schedulers.from(executor) 使用指定的Executor作为调度器
Schedulers.immediate() 在当前线程立即开始执行任务
Schedulers.io() 用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io()默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器
Schedulers.newThread() 为每个任务创建一个新线程
Schedulers.trampoline() 当其它排队的任务完成后,在当前线程排队开始执行

2.6 事件调度器

RxJava事件发出去并不是置之不顾,要有合理的管理者来管理它们,在合适的时机要进行释放事件,这样才不会导致内存泄漏,这里的管理者我们称为事件调度器(或事件管理者)CompositeDisposable。Rxjava的事件流发出去后,会返回Disposable类型的对象,我们可以将该对象添加到事件调度器上,然后进行相关操作,这里的事件调度器我们可以简单的理解为事件的容器

public class Main {

    private static CompositeDisposable mRxEvent = new CompositeDisposable();

    public static void main(String[] args) {
        Disposable subscribe = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
                e.onNext("俊俊俊很帅");
                e.onNext("你值得拥有");
                e.onNext("取消关注");
                e.onNext("但还是要保持微笑");
                e.onComplete();
            }
        }).subscribe(
                new Consumer<String>() {
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        //对应onNext()
                        System.out.println("accept=" + s);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        //对应onError()
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        //对应onComplete()
                    }
                }, new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {
                        //对应onSubscribe()
                    }
                });
        
        mRxEvent.add(subscribe);
        mRxEvent.clear();
    }
}

CompositeDisposable提供的方法中,都是对事件的管理

  • dispose():释放所有事件
  • clear():释放所有事件,实现同dispose()
  • add():增加某个事件
  • addAll():增加所有事件
  • remove():移除某个事件并释放
  • delete():移除某个事件

2.7 "冷"与"热"

RxJava的事件发射分为冷与热,一个"热"的Observable可能一创建完就开始发射数据,因此所有后续订阅它的观察者可能从序列中间的某个位置开始接受数据(有一些数据错过了)。一个"冷"的Observable会一直等待,直到有观察者订阅它才开始发射数据,因此这个观察者可以确保会收到整个数据序列

2.8 小结

RxJava可以简单的归结为三步骤

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

推荐阅读更多精彩内容