Delay

delay的意思就是延迟,这个操作符会延迟一段指定的时间再发射Observable的数据。 RxJava的实现是 delay和delaySubscription。

delay:让原始Observable在发射每项数据之前都暂停一段指定的时间段,结果是Observable发射的数据项在时间上整体延后一段时间。

注意:delay不会平移onError通知,它会立即将这个通知传递给订阅者,同时丢弃任何待发射的onNext通知。但是它会平移一个onCompleted通知。

    

RxJava操作符——辅助操作符(Observable Utility Operators)_ide

    delaySubscription:和delay不同的是,delaySubscription是延迟订阅原始Observable,这样也能达到数据延迟发射的效果。

RxJava操作符——辅助操作符(Observable Utility Operators)_操作符_02


示例代码:

Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS).take(5);
/*
* Delay操作符让原始Observable在发射每项数据之前都暂停一段指定的时间段。
* 效果是Observable发射的数据项在时间上向前整体平移了一个增量
*
* 注意:delay不会平移onError通知,它会立即将这个通知传递给订阅者,同时丢弃任何待发射的onNext通知。
* 然而它会平移一个onCompleted通知。
*/
observable
.delay(3, TimeUnit.SECONDS)
.subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onNext(Long value) {
System.out.println("delay onNext value :"+ value);
}
});

/*
* delaySubscription:延迟订阅原始Observable
*/
observable
.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onNext(Long value) {
System.out.println("delaySubscription onNext value :"+ value);
}
});

输出:

delay onNext value :0
delay onNext value :1
delay onNext value :2
delay onNext value :3
delay onNext value :4
onCompleted

delaySubscription onNext value :0
delaySubscription onNext value :1
delaySubscription onNext value :2
delaySubscription onNext value :3
delaySubscription onNext value :4
onCompleted

Do

Do系列操作符就是为原始Observable的生命周期事件注册一个回调,当Observable的某个事件发生时就会调用这些回调。RxJava实现了很多doxxx操作符:

RxJava操作符——辅助操作符(Observable Utility Operators)_操作符_03

  

  • doOnEach:为 Observable注册这样一个回调,当Observable没发射一项数据就会调用它一次,包括onNext、onError和 onCompleted
  • doOnNext:只有执行onNext的时候会被调用
  • doOnSubscribe: 当观察者(Sunscriber)订阅Observable时就会被调用
  • doOnUnsubscribe: 当观察者取消订阅Observable时就会被调用;Observable通过onError或者onCompleted结束时,会反订阅所有的Subscriber
  • doOnCompleted:当Observable 正常终止调用onCompleted时会被调用。
  • doOnError: 当Observable 异常终止调用onError时会被调用。
  • doOnTerminate: 当Observable 终止之前会被调用,无论是正常还是异常终止
  • finallyDo: 当Observable 终止之后会被调用,无论是正常还是异常终止。

示例代码:

Observable.just(1,2,3,4,5,6)
.doOnEach(new Action1<Notification<? super Integer>>() {

@Override
public void call(Notification<? super Integer> t) {
System.out.println("doOnEach value = " + t.getValue());
}
})
.doOnError(new Action1<Throwable>() {

@Override
public void call(Throwable t) {
System.out.println("doOnError " + t);

}
})
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}

@Override
public void onError(Throwable e) {
System.out.println("onError: " + e.getMessage());
}

@Override
public void onNext(Integer integer) {
System.out.println("onNext: "

输出:

doOnSubscribe
doOnEach value = 1
onNext: 1
doOnEach value = 2
onNext: 2
doOnEach value = 3
onNext: 3
doOnEach value = 4
onNext: 4
doOnEach value = 5
onNext: 5
doOnEach value = 6
onNext: 6
doOnEach value = null
doOnCompleted
onCompleted
doAfterTerminate

Materialize/Dematerialize

materialize将来自原始Observable的通知(onNext/onError/onComplete)都转换为一个Notification对象,然后再按原来的顺序一次发射出去。

Dematerialize操作符是Materialize的逆向过程,它将Materialize转换的结果还原成它原本的形式( 将Notification对象还原成Observable的通知)

RxJava操作符——辅助操作符(Observable Utility Operators)_操作符_04

  

示例代码:

Observable.just(1,2,3,4,5,6).materialize()
.subscribe(new Action1<Notification>() {

@Override
public void call(Notification t) {
//这里,onComplete也被meterialize包装后发射了出来,onError也同样。
System.out.println("meterialize:" + t.getValue() + " type " + t.getKind());
}
});
System.out.println("-------------------------");

//将Notification逆转为普通消息发射
Observable<Integer> observable = Observable.just(1,2,3,4,5,6).materialize().dematerialize();
observable.subscribe(new Action1<Integer>() {

@Override
public void call(Integer value) {
System.out.println("onNext: " + value);
}
});

输出:

meterialize:1   type OnNext
meterialize:2 type OnNext
meterialize:3 type OnNext
meterialize:4 type OnNext
meterialize:5 type OnNext
meterialize:6 type OnNext
meterialize:null type OnCompleted
-------------------------
onNext: 1
onNext: 2
onNext: 3
onNext: 4
onNext: 5
onNext: 6

ObserveOn/SubscribeOn

这两个操作符对于Android开发来说非常适用,因为Android中只能在主线程中修改UI,耗时操作不能在主线程中执行,所以我们经常会创建新的Thread去执行耗时操作,然后配合Handler修改UI,或者使用AsyncTask。RxJava中使用这两个操作符能够让我们非常方便的处理各种线程问题。

  • SubscribeOn:指定Observable自身在哪个调度器上执行(即在那个线程上运行),如果Observable需要执行耗时操作,一般我们可以让其在新开的一个子线程上运行,好比AsyncTask的doInBackground方法。
  • RxJava操作符——辅助操作符(Observable Utility Operators)_操作符_05

  • ObserveOn:可以使用observeOn操作符指定Observable在哪个调度器上发送通知给观察者(调用观察者的onNext,onCompleted,onError方法)。一般我们可以指定在主线程中观察,这样就可以修改UI,相当于AsyncTask的onPreExecute 、onPrograssUpdate和onPostExecute 方法中执行

RxJava操作符——辅助操作符(Observable Utility Operators)_操作符_06


关于RxJava的多线程调度器“Scheduler”,后面会有一篇博客详细介绍。

示例代码:

Observable<Integer> observable = Observable.just(1,2);

observable.subscribeOn(Schedulers.io())
.map(new Func1<Integer, Integer>() {

@Override
public Integer call(Integer t) {
System.out.println("map thread : " + Thread.currentThread().getName());
return t * 10;
}
})
.observeOn(Schedulers.newThread())//对应android是:AndroidSchedulers.mainThread()
.subscribe(new Action1<Integer>() {

@Override
public void call(Integer value) {
System.out.println("subscribe thread : " + Thread.currentThread().getName());
System.out.println("onNext: " + value);
}
});

输出:

map thread : RxIoScheduler-2
map thread : RxIoScheduler-2
subscribe thread : RxNewThreadScheduler-1
onNext: 10
subscribe thread : RxNewThreadScheduler-1
onNext: 20

TimeInterval

TimeInterval操作符拦截原始Observable发射的数据项,替换为两个连续发射物之间流逝的时间长度。 也就是说这个使用这个操作符后发射的不再是原始数据,而是原始数据发射的时间间隔。新的Observable的第一个发射物表示的是在观察者订阅原始Observable到原始Observable发射它的第一项数据之间流逝的时间长度。 不存在与原始Observable发射最后一项数据和发射onCompleted通知之间时长对应的发射物。timeInterval默认在immediate调度器上执行,你可以通过传参数修改。

RxJava操作符——辅助操作符(Observable Utility Operators)_操作符_07


示例代码:

Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 3; i <= 7; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
subscriber.onNext(i);
}
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())
.timeInterval()
.subscribe(new Subscriber<TimeInterval<Integer>>() {

@Override
public void onCompleted() {
System.out.println("onCompleted");
}

@Override
public void onError(Throwable e) {
}

@Override
public void onNext(TimeInterval<Integer> t) {
System.out.println("onNext: " + t.getValue() + " - "

输出:

onNext: 3 - 1002
onNext: 4 - 1006
onNext: 5 - 1003
onNext: 6 - 1005
onNext: 7 - 1003

Timeout

如果原始Observable过了指定的一段时长没有发射任何数据,Timeout操作符会以一个onError通知终止这个Observable,或者继续一个备用的Observable。

RxJava操作符——辅助操作符(Observable Utility Operators)_操作符_07


RxJava中的实现的Timeout操作符有好几个变体:

  • timeout(long,TimeUnit): 第一个变体接受一个时长参数,每当原始Observable发射了一项数据,timeout就启动一个计时器,如果计时器超过了指定指定的时长而原始Observable没有发射另一项数据,timeout就抛出TimeoutException,以一个错误通知终止Observable。 这个timeout默认在computation调度器上执行,你可以通过参数指定其它的调度器。
  • timeout(long,TimeUnit,Observable): 这个版本的timeout在超时时会切换到使用一个你指定的备用的Observable,而不是发错误通知。它也默认在computation调度器上执行。
  • timeout(Func1):这个版本的timeout使用一个函数针对原始Observable的每一项返回一个Observable,如果当这个Observable终止时原始Observable还没有发射另一项数据,就会认为是超时了,timeout就抛出TimeoutException,以一个错误通知终止Observable。
  • timeout(Func1,Observable): 这个版本的timeout同时指定超时时长和备用的Observable。它默认在immediate调度器上执行
  • timeout(Func0,Func1):这个版本的time除了给每一项设置超时,还可以单独给第一项设置一个超时。它默认在immediate调度器上执行。
  • timeout(Func0,Func1,Observable): 同上,但是同时可以指定一个备用的Observable。它默认在immediate调度器上执行。
    示例代码:
Observable<Integer> observable = Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(i*100);
} catch (InterruptedException e) {
e.printStackTrace();
}
subscriber.onNext(i);
}
subscriber.onCompleted();
}
});

observable
.timeout(200, TimeUnit.MILLISECONDS, Observable.just(100,200))
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}

@Override
public void onError(Throwable e) {
System.out.println("onError: " + e.getMessage());
}

@Override
public void onNext(Integer integer) {
System.out.println("onNext: "

输出:

onNext: 0
onNext: 1
onNext: 100
onNext: 200
onCompleted

Timestamp

它将一个发射T类型数据的Observable转换为一个发射类型为Timestamped的数据的Observable,每一项都包含数据的发射时间。也就是把Observable发射的数据重新包装了一下,将数据发射的时间打包一起发射出去,这样观察者不仅能得到数据,还能得到数据的发射时间。 timestamp默认在immediate调度器上执行,但是可以通过参数指定其它的调度器。

RxJava操作符——辅助操作符(Observable Utility Operators)_ide_09


示例代码:

Observable.just(1,2,3)
.timestamp()
.subscribe(new Subscriber<Timestamped<Integer>>() {
@Override
public void onCompleted() {
}

@Override
public void onError(Throwable e) {
}

@Override
public void onNext(Timestamped<Integer> t) {
System.out.println("onNext: " + t.getValue() + " ,time:"

输出:

onNext: 1 ,time:1486018751879
onNext: 2 ,time:1486018751880
onNext: 3 ,time:1486018751880

Using

Using操作符指示Observable创建一个只在它的生命周期内存在的资源,当Observable终止时这个资源会被自动释放。
using操作符接受三个参数:

  • 一个用于 创建一次性资源的工厂函数
  • 一个用于创建Observable的工厂函数
  • 一个用于释放资源的函数

当一个观察者订阅using返回的Observable时,using将会使用Observable工厂函数创建观察者要观察的Observable,同时使用资源工厂函数创建一个你想要创建的资源。当观察者取消订阅这个Observable时,或者当观察者终止时(无论是正常终止还是因错误而终止),using使用第三个函数释放它创建的资源。

RxJava操作符——辅助操作符(Observable Utility Operators)_视频教程_10

示例代码:

Observable.from(studentList)
.using(new Func0<Integer>() {

@Override
public Integer call() {
return new Random().nextInt(100);
}
}, new Func1<Integer, Observable<String>>() {

@Override
public Observable<String> call(Integer t) {
return Observable.just("西部世界接待员-" + t);

}
}, new Action1<Integer>() {

@Override
public void call(Integer t) {
t = null;
}
}).subscribe(new Action1<String>() {

@Override
public void call(String t) {
System.out.println("call : "

输出:

call : 西部世界接待员-64

To

将Observable转换为另一个对象或数据结构。它们中的一些会阻塞直到Observable终止,然后生成一个等价的对象或数据结构;另一些返回一个发射那个对象或数据结构的Observable。简而言之就是,将原始Observable转化为一个发射另一个对象或者数据结构的Observable,如果原Observable发射完他的数据需要一段时间,使用To操作符得到的Observable将阻塞等待原Observable发射完后再将数据序列打包后发射出去。

RxJava操作符——辅助操作符(Observable Utility Operators)_ide_11

RxJava中实现了如下几种To操作符:

  • toList:发射多项数据的Observable会为每一项数据调用onNext方法,用toList操作符让Observable将多项数据组合成一个List,然后调用一次onNext方法传递整个列表。
    如果原始Observable没有发射任何数据就调用了onCompleted,toList返回的Observable会在调用onCompleted之前发射一个空列表。如果原始Observable调用了onError,toList返回的Observable会立即调用它的观察者的onError方法。
  • toMap: toMap收集原始Observable发射的所有数据项到一个Map(默认是HashMap)然后发射这个Map。你可以提供一个用于生成Map的Key的函数,还可以提供一个函数转换数据项到Map存储的值(默认数据项本身就是值)。
  • toMultiMap:toMultiMap类似于toMap,不同的是,它生成的这个Map同时还是一个ArrayList(默认是这样,你可以传递一个可选的工厂方法修改这个行为)。
  • toSortedList:toSortedList类似于toList,不同的是,它会对产生的列表排序,默认是自然升序,如果发射的数据项没有实现Comparable接口,会抛出一个异常。然而,你也可以传递一个函数作为用于比较两个数据项,这是toSortedList不会使用Comparable接口。
  • toFuture:toFuture操作符只能用于BlockingObservable(首先必须把原始的Observable转换为一个BlockingObservable。可以使用这两个操作符:BlockingObservable.from或the Observable.toBlocking)。这个操作符将Observable转换为一个返回单个数据项的Future,如果原始Observable发射多个数据项,Future会收到一个IllegalArgumentException;如果原始Observable没有发射任何数据,Future会收到一个NoSuchElementException。
    如果你想将发射多个数据项的Observable转换为Future,可以这样用:myObservable.toList().toBlocking().toFuture()。
  • toIterable:只能用于BlockingObservable。这个操作符将Observable转换为一个Iterable,你可以通过它迭代原始Observable发射的数据集。

示例代码:

Observable.interval(500, TimeUnit.MILLISECONDS).take(3)
.toList()
.subscribe(new Subscriber<List<Long>>() {
@Override
public void onCompleted() {

}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(List<Long> longs) {
System.out.println("onNext : "

输出:

onNext : [0, 1, 2]