Android拾萃 - RxJava2之创建操作符及其demo

根据下图,再一次回顾一下前面几章的内容,经典的三步法等内容。
Android拾萃 - RxJava操作符和响应类型(二) 的图片。

RxJava 2.x的5种响应类型

一、创建操作符列表

名称 解析
just() 将一个或多个对象转换成发射这个或这些对象的一个Observable
fromArray() 将一个Iterable, 一个Future, 或者一个数组转换成一个Observable
repeat() 创建一个重复发射指定数据或数据序列的Observable
repeatWhen() 创建一个重复发射指定数据或数据序列的Observable,它依赖于另一个Observable发射的数据
create() 使用一个函数从头创建一个Observable
defer() 只有当订阅者订阅才创建Observable;为每个订阅创建一个新的Observable
range() 创建一个发射指定范围的整数序列的Observable
interval() 创建一个按照给定的时间间隔发射整数序列的Observable
timer() 创建一个在给定的延时之后发射单个数据的Observable
empty() 创建一个什么都不做直接通知完成的Observable
error() 创建一个什么都不做直接通知错误的Observable
never() 创建一个入不发射任何数据的Observable

二、创建操作符例子

Observable + 操作符 + subscribe + observer,就构成了一个完整的例子。
由于只是做展示,observer基本可以公用,这里写成一个静态变量,详细见代码。而对于操作符,我们可以简单理解,就是对onexst onerror oncomplete 还有一些传入参数和方法的封装,起到简化代码的作用。

just.png

just 可以发射一个或者多个对象,会依次回调onNext,并最后自动调用onComplete(可以理解为对上述多个onNext和一个onComplete操作的封装)

 private static  Observer observer = new Observer<String>() {
        @Override
        public void onSubscribe(@NonNull Disposable d) {
        }

        @Override
        public void onNext(@NonNull String s) {
            Log.i(TAG, s);
        }

        @Override
        public void onError(@NonNull Throwable e) {
            Log.i(TAG, "onError");
        }

        @Override
        public void onComplete() {
            Log.i(TAG, "onCompleted");
        }
    };


 //just 发射了三个对象,会依次回调onNext,并最后自动调用onComplete
        Observable.just("A","B","C").subscribe(observer);

执行程序,console打印信息如下:

10-19 01:02:20.758 20699-20699/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: A
10-19 01:02:20.758 20699-20699/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: B
10-19 01:02:20.758 20699-20699/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: C
10-19 01:02:20.758 20699-20699/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: onCompleted
defer.png

defer 创建的Observable将推迟到subscribe订阅的时候(这个时候会调用call()方法进行发射数据),但是这个时候监听到的数据可能和创建的时候的数据不一致了,如图上的两种颜色,代表两种不同数据。

//final 数组只是引用地址不变,值还是可以改变的
        final String[] str={"hi, rxjava"};
        Observable observable =Observable.defer(new Callable<ObservableSource<?>>() {
            @Override
            public ObservableSource<?> call() throws Exception {
                return Observable.just(str[0]);
            }
        });

        str[0]="hi, i have changed";

        observable.subscribe(observer);

我们看到打印信息里面 str[0]确实是改变了的

10-19 01:11:57.428 29288-29288/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: hi, i have changed
10-19 01:11:57.428 29288-29288/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: onCompleted

empty()/error()/never()

 //直接调用onComplete
        Observable.empty().subscribe(observer);
        //直接回调onError
        Observable.error(new Throwable("some error")).subscribe(observer);
        //啥事不干
        Observable.never().subscribe(observer);
10-19 01:13:56.228 31014-31014/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: onCompleted
10-19 01:13:56.228 31014-31014/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: onError
fromArray.png

rxjava1 是from 而rxjava2 应该是fromArray,图上是不对的。fromArray 发射的是一个数组对象,但是却可以依次接收到数组的各个元素,其实just最终调用的也是fromArray

        Observable.fromArray(new String[]{"A","B","C"}).subscribe(observer);
10-19 01:17:20.618 1368-1368/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: A
10-19 01:17:20.618 1368-1368/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: B
10-19 01:17:20.618 1368-1368/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: C
10-19 01:17:20.628 1368-1368/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: onCompleted

repeat() 默认是Long.MAX_VALUE,即无限重复,repeat(5)表示重复5次。
repeat 和 retry 的操作符都有相对应的操作符,但是两类操作符是有区别的。
.repeat()是接收到.onCompleted()事件后触发重订阅。而.retry()接收到.onError()事件后触发重订阅。

        Observable.just("A").repeat().subscribe(observer);
        Observable.just("A","B","C").repeat(5).subscribe(observer);
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: A
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: B
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: C
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: A
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: B
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: C
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: A
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: B
10-19 01:20:21.148 4994-4994/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: C
10-19 01:20:21.
repeatWhen.f.png

range(1, 5) 从1开始发射到5
repeatWhen 需要传入一个方法或者条件,包装方法我们可以使用flatMap

我们就来实现一个定时器例子
使用timer(5秒执行一次),即5秒repeat一次

timer.p.png

怎么写出以下代码,基本我们知道需求和使用什么操作符,按照代码提示就可以写了,多敲敲代码才是王道~

        Observable.range(1, 5).repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(@NonNull Observable<Object> objectObservable) throws Exception {

                return objectObservable.flatMap(new Function<Object, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(@NonNull Object o) {

                        return Observable.timer(5, TimeUnit.SECONDS);
                    }
                });
            }
        }).subscribe(observer);
//range发射的是int值的,前面observer是String泛型的,所以这里也需要更改
 private static  Observer observer = new Observer<Integer>() {
        @Override
        public void onSubscribe(@NonNull Disposable d) {
        }

        @Override
        public void onNext(@NonNull Integer s) {
            Log.i(TAG, s+"");
        }

        @Override
        public void onError(@NonNull Throwable e) {
            Log.i(TAG, "onError");
        }

        @Override
        public void onComplete() {
            Log.i(TAG, "onCompleted");
        }
    };
10-19 01:24:30.928 9114-9114/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 1
10-19 01:24:30.928 9114-9114/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 2
10-19 01:24:30.928 9114-9114/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 3
10-19 01:24:30.928 9114-9114/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 4
10-19 01:24:30.928 9114-9114/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 5

10-19 01:24:35.948 9114-9332/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 1
10-19 01:24:35.948 9114-9332/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 2
10-19 01:24:35.948 9114-9332/com.example.philos.rxjavademo I/Cre

ateOperateExampleActiivty: 3
10-19 01:24:35.948 9114-9332/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 4
10-19 01:24:35.948 9114-9332/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 5
interval.png

interval 每秒发射一次,并且递增.这里发射的是long类型的数据,所以observer也需要重写

    private static  Observer observer = new Observer<Long>() {
        @Override
        public void onSubscribe(@NonNull Disposable d) {
        }

        @Override
        public void onNext(@NonNull Long s) {
            Log.i(TAG, s+"");
        }

        @Override
        public void onError(@NonNull Throwable e) {
            Log.i(TAG, "onError");
        }

        @Override
        public void onComplete() {
            Log.i(TAG, "onCompleted");
        }
    };

        Observable.interval(1, TimeUnit.SECONDS).subscribe(observer);
10-19 01:29:57.838 11742-12139/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 0
10-19 01:29:58.838 11742-12139/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 1
10-19 01:29:59.838 11742-12139/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 2
10-19 01:30:00.838 11742-12139/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 3
10-19 01:30:01.838 11742-12139/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 4                 
 beginning of /dev/log/system
10-19 01:30:02.838 11742-12139/com.example.philos.rxjavademo I/CreateOperateExampleActiivty: 5

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

推荐阅读更多精彩内容