Rxjava入门(二)

通过上一节的学习我们知道了rxjava是什么(需要看一的朋友点这里Rxjava入门 一),以及怎样利用rxjava打印输出字符串和数组。总结起来就是:Observable发射事件,subscribe订阅observable事件并迭代执行。


但是我们知道我们平时所接触的事件流程远远没有这么简单。有时候我们需要把数据经过复杂的变换然后才能为我们所用。同样,rxjava的开发人员也已经为我们想到了这些。并且创造了一系列操作符为我们所用。

创建操作

上一节我们已经接触了from和just两个创建方式,其实也是两个操作符。
除此之外还有Create、Range、Repeat、Start、Timer等方式

Create

官方解释:使用一个函数从头开始创建一个Observable
你可以使用 Create 操作符从头开始创建一个Observable,给这个操作符传递一个接受观察者 作为参数的函数,编写这个函数让它的行为表现为一个Observable--恰当的调用观察者的 onNext,onError和onCompleted方法。
  一个形式正确的有限Observable必须尝试调用观察者的onCompleted正好一次或者它的 onError正好一次,而且此后不能再调用观察者的任何其它方法。
  RxJava将这个操作符实现为 create 方法。
  建议你在传递给 create 方法的函数中检查观察者的 isUnsubscribed 状态,以便在没有观察者的时候,让你的Observable停止发射数据或者做昂贵的运算。

示例代码:

Observable.create(new Observable.OnSubscribe<Integer>() {
   @Override
   public void call(Subscriber<? super Integer> observer) {
       try {
           if (!observer.isUnsubscribed()) {
               for (int i = 1; i < 5; i++) {
                   observer.onNext(i);
               }
               observer.onCompleted();
           }
       } catch (Exception e) {
           observer.onError(e);
} }
} ).subscribe(new Subscriber<Integer>() {
       @Override
       public void onNext(Integer item) {
           System.out.println("Next: " + item);
}
       @Override
       public void onError(Throwable error) {
           System.err.println("Error: " + error.getMessage());
       }
       @Override
       public void onCompleted() {
           System.out.println("Sequence complete.");
       }
});


从例子我们可以看到。重新创建一个observable我们可以掌控订阅者对事件的执行方式。

Repeat

创建一个发射特定数据重复多次的Observable
  Repeat重复地发射数据。某些实现允许你重复的发射某个数据序列,还有一些允许你限制重 复的次数。
  RxJava将这个操作符实现为 repeat 方法。它不是创建一个Observable,而是重复发射原始 Observable的数据序列,这个序列或者是无限的,或者通过 repeat(n) 指定重复次数。
  repeat 操作符默认在 trampoline 调度器上执行。有一个变体可以通过可选参数指定 Scheduler。

repeat

关于创建的操作符就讲到这里,相关的其它方式可以在这里查看

变换操作符

变换操作符的目的是讲数据变为我们需要的类型,常见的变换操作符有 Buffer、FlatMap、GroupBy、Map、Scan。

Map操作符

官方解释:Map 操作符对原始Observable发射的每一项数据应用一个你选择的函数,然后返回一个发射 这些结果的Observable。

使用map操作符,我们可以将数据转换后再进行发射

map

  如图所示,我们将每个数据*10然后输出数据会依次按照原始顺序*10然后输出.

下面我们举个例子

 Observable.just("1010101010").map(new Func1<String, Integer>() {
            @Override
            public Integer call(String s) {
                return Integer.parseInt(s);
            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                System.out.println(integer);
            }
        });


06-03 14:55:13.927 358-358/? I/System.out: 1010101010

我们可以看到,我们通过map操作符将String类型转换为int类型然后打印输出。map泛型第一个参数是原始数据类型,第二个是你需要的类型。在此不再过多赘述。

FlatMap操作符

官方解释:FlatMap 将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据合并 后放进一个单独的Observable
  FlatMap 操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这 个函数返回一个本身也发射数据的Observable,然后 FlatMap 合并这些Observables发射的数 据,最后将合并后的结果当做它自己的数据序列发射。
  这个方法是很有用的,例如,当你有一个这样的Observable:它发射一个数据序列,这些数 据本身包含Observable成员或者可以变换为Observable,因此你可以创建一个新的 Observable发射这些次级Observable发射的数据的完整集合。

flatmap

官网文档意思是,利用flatmap可以将一个Observable发射的数据转换成多个Observable发射,然后将其发射的数据整合到一起,组成所需要的发射序列

我们来举个例子

<pre>
Observable.just("a.b.c.d.e.f.g").flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
return Observable.from(s.split("\."));
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

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

06-03 15:09:29.456 13428-13428/? I/System.out: a
06-03 15:09:29.456 13428-13428/? I/System.out: b
06-03 15:09:29.456 13428-13428/? I/System.out: c
06-03 15:09:29.456 13428-13428/? I/System.out: d
06-03 15:09:29.456 13428-13428/? I/System.out: e
06-03 15:09:29.456 13428-13428/? I/System.out: f
06-03 15:09:29.456 13428-13428/? I/System.out: g

</pre>

从代码中我们可以看到,我将字符串“a.b.c.d.e.f.g”用.符号分割开成长度为7的字符数组,然后利用Observable.from方式重新创建了数量为7的发射序列,然后依次进行发射。然后在依次subscribe中执行。
  变换操作符就先讲到这里,剩下的可在这里学习.

过滤操作符

过滤操作符可以用于过滤和选择Observable发射的数据序列。常见的过滤操作符有 filter、takeLast、skip、skipLast、take、first、takeFirst、timeout等。过滤操作符看字面意思我想你已经知道差不多了。在这里我们不做重点解释。先举几个例子。

Filter

官方解释:只发射通过了谓词测试的数据项。
Filter 操作符使用你指定的一个谓词函数测试数据项,只有通过测试的数据才会被发射。

示例代码:


Observable.just(1, 2, 3, 4, 5)
          .filter(new Func1<Integer, Boolean>() {
              @Override
              public Boolean call(Integer item) {
                return( item < 4 );
              }
          }).subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }
        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }
        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
});

输出

Next: 1
Next: 2
Next: 3
Sequence complete.

剩余的操作符可以在这里这里继续学习。

rxjava操作符类型还有很多,这里就不再列举了,有需要的可以看官方文档。这里还有一本中文版文档。需要的请点击阅读或下载。

Rxjava结合RxAndroid使用

调度器(Scheduler)

说到这里我们先提一下调度器的概念。

如果你想给Observable操作符链添加多线程功能,你可以指定操作符(或者特定的 Observable)在特定的调度器(Scheduler)上执行。
  某些ReactiveX的Observable操作符有一些变体,它们可以接受一个Scheduler参数。这个参 数指定操作符将它们的部分或全部任务放在一个特定的调度器上执行。
  使用ObserveOn和SubscribeOn操作符,你可以让Observable在一个特定的调度器上执行, ObserveOn指示一个Observable在一个特定的调度器上调用观察者的onNext, onError和 onCompleted方法,SubscribeOn更进一步,它指示Observable将全部的处理过程(包括发射 数据和通知)放在特定的调度器上执行。

Android是UI单线程的,所以在进行大量数据处理或者请求网络的时候我们经常要用到开启子线程异步处理数据。这时候我们就需要用到调度器了.
Rxjava使用调度器为我们提供了多种开启异步的方式。
如图:

rxjava_schedule

看图得知,Schedulers.io( )操作符处理异步数据时是最适合我们使用的。

指定一个观察者在哪个调度器上观察这个Observable,我们可以使用ObserveOn操作符
  指定Observable自身在哪个调度器上执行我们可以使用SubscribeOn操作符

RxAndroid

RxAndroid是Rxjava的扩展,是由JakeWharton编写,目的是使Android可以优雅地处理异步请求并且完美融合Rxjava使用。RxAndroid为我们提供了一个AndroidSchedulers.mainThread()调度器,我们可以在observer中自由切换线程。

我们先写个例子:

 Observable.just("one", "two", "three", "four", "five")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(/* an Observer */);

这样Observable会在子线程里处理事件,处理结果会发送到onnext回调方法中去。

今天就先说这么多了,这一篇主要讲了Rxjava的操作符和RxAndroid使用,下一章将结合Retrofit使用。

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

推荐阅读更多精彩内容

  • 本篇文章介主要绍RxJava中操作符是以函数作为基本单位,与响应式编程作为结合使用的,对什么是操作、操作符都有哪些...
    嘎啦果安卓兽阅读 2,841评论 0 10
  • 作者寄语 很久之前就想写一个专题,专写Android开发框架,专题的名字叫 XXX 从入门到放弃 ,沉淀了这么久,...
    戴定康阅读 7,615评论 13 85
  • 创建操作 用于创建Observable的操作符Create通过调用观察者的方法从头创建一个ObservableEm...
    rkua阅读 1,801评论 0 1
  • 作者: maplejaw本篇只解析标准包中的操作符。对于扩展包,由于使用率较低,如有需求,请读者自行查阅文档。 创...
    maplejaw_阅读 45,600评论 8 93
  • 响应式编程简介 响应式编程是一种基于异步数据流概念的编程模式。数据流就像一条河:它可以被观测,被过滤,被操作,或者...
    说码解字阅读 3,052评论 0 5