rxjava2创建运算符
rxjava2支持链式编程,大多数运算符都在Observable上运行并返回一个Observable。 这允许我们在链中一个接一个地应用这些运算符。 链中的每个运算符都会修改由前一个运算符的运算产生的Observable。
rxjava提供了大量不同种类的运算操作符,根据其分类来划分,大致可以分为以下列表
分类 | 举例 | 说明 |
---|---|---|
Creating Observables | Create、Defer 、Empty/Never/Throw、From 、Interval 、Just 、Range 、Repeat 、Start 、Timer | 创建运算符,用于创建Observable |
Transforming Observables | Buffer 、FlatMap、GroupBy、Map、Scan、Window | 变换运算符,用于将Observable发出的项进行转换 |
Filtering Observables | Debounce、Distinct、ElementAt、Filter 、First 、IgnoreElements 、Last 、Sample、Skip 、SkipLast 、Take 、TakeLast | 过滤运算符,将源Observable发出的项有选择的过滤 |
Combining Observables | And/Then/When 、CombineLatest、Join 、Merge 、StartWith 、Switch 、Zip | 组合运算符,使用多个源Observable创建单个Observable |
Error Handling Operators | Catch、Retry | 错误处理运算符,有助于从Observable中恢复错误通知 |
Observable Utility Operators | Delay、Do、Materialize/Dematerialize 、ObserveOn、Serialize 、Subscribe 、SubscribeOn、TimeInterval 、Timeout、Timestamp、Using | 工具运算符,用于处理常见场景Observable的辅助工具 |
Conditional and Boolean Operators | All 、Amb 、Contains 、DefaultIfEmpty 、SequenceEqual 、SkipUntil、SkipWhile 、TakeUntil、TakeWhile | 条件和布尔运算符 |
Mathematical and Aggregate Operators | Average 、Concat、Count 、Max、Min 、Reduce、Sum | 运算和聚合运算符 |
Backpressure Operators | backpressure operators | 被压策略运算 |
Connectable Observable Operators | Connect、Publish 、RefCount 、Replay | 可连接的可观察操作符,具有更精确控制的订阅动态的专业观察者 |
Operators to Convert Observables | To | 转换Observables的运算符,将Observable转换为另一个对象或数据结构 |
这么一看感觉东西不少,但其实rxjava2中已经去掉、替换了许多常用的运算符和场景的实现方法,我们先一步一步来,选取其中简单高频的运算操作符,从易到难慢慢了解下,这一章就先看下常见创建Observable的方法。
Create
使用Create运算符从头开始创建Observable。适当地调用观察者的onNext,onError和onCompleted方法。一个格式良好的Observable必须尝试只调用一次观察者的onCompleted方法或者只调用一次onError方法,并且此后不得尝试调用任何观察者的其他方法。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
for (int i = 1; i < 3; i++) {
emitter.onNext("emitter "+i);
}
emitter.onComplete();
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.d(TAG, " onNext : s : " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG, " onComplete");
}
});
打印结果
onNext : s : emitter 1
onNext : s : emitter 2
onComplete
Just
创建一个发出特定项目的Observable。Just只是简单地发出数组或者你有什么,不变 ,作为单个项目发出。当just后传入item是String时,发射出来的为onNext(String s);当just后传入的item是string[]时,发射出来的为onNext(String[] strings)。
下面我举下例子,说明下:
当just后传入item是String时
Observable.just("0","1","2","3","4","5","6","7","8","9")
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, " accept : value : " + s);
}
});
打印结果为
onNext : accept : 0
onNext : accept : 1
onNext : accept : 2
onNext : accept : 3
onNext : accept : 4
onNext : accept : 5
onNext : accept : 6
onNext : accept : 7
onNext : accept : 8
onNext : accept : 9
当just后传入item是string[]时
String str[] = {"0","1","2","3","4","5","6","7","8","9"};
Observable.just(str)
.subscribe(new Consumer<String[]>() {
@Override
public void accept(String[] strings) throws Exception {
Log.d(TAG, " accept : value String[] length: " + strings.length);
}
});
打印结果
accept : value String[] length: 10
与rxjava1.0不同的是,rxjava2不在允许传递null,rxjava2 just中直接传递null会抛出异常,而且just可传递的item个数最多只能是10个。
Observable.just(null);//会造成异常
查看just源码可以看见以下代码
public static <T> Observable<T> just(T item) {
ObjectHelper.requireNonNull(item, "The item is null");
return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
}
public static <T> T requireNonNull(T object, String message) {
if (object == null) {
//抛出异常
throw new NullPointerException(message);
}
return object;
}
fromArray
将各种其他对象和数据类型转换为Observable。与just相同的是,rxjava2 fromArray中直接传递null会抛出异常。但与just不同的是fromArray发射数组时,它是逐个发射数组的元素。而just发射数组时,会把它当成一个整体,直接发射出去。
String str[] = {"0","1","2","3","4","5","6","7","8","9"};
Observable.fromArray(str)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, " accept : value : " + s);
}
});
accept : value : 0
accept : value : 1
accept : value : 2
accept : value : 3
accept : value : 4
accept : value : 5
accept : value : 6
accept : value : 7
accept : value : 8
accept : value : 9
Range
创建一个发出特定范围的连续整数的Observable。Range运算符按顺序发出一系列连续的整数,我们可以在其中选择范围的起点及其长度。
举个例子,从5开始输出10个连续的数
Observable.range(5,10)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, " accept : value : " + integer);
}
});
打印结果
accept : value : 5
accept : value : 6
accept : value : 7
accept : value : 8
accept : value : 9
accept : value : 10
accept : value : 11
accept : value : 12
accept : value : 13
accept : value : 14
Interval
Interval运算符返回一个Observable,它发出无限的升序整数序列,并在排放之间选择一个恒定的时间间隔。
举个例子,一秒之后开始发送,每次发送间隔两秒
private final CompositeDisposable disposables = new CompositeDisposable();
private void doSomeWork() {
Log.d(TAG, " doSomeWork time : "+System.currentTimeMillis());
disposables.add(Observable.interval(1, 2, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.d(TAG, " accept : value : " + aLong +", time : "+System.currentTimeMillis());
}
}));
}
@Override
protected void onDestroy() {
super.onDestroy();
disposables.clear(); // clearing it : do not emit after destroy
}
打印结果
doSomeWork time : 1539339380740
accept : value : 0, time : 1539339381744
accept : value : 1, time : 1539339383743
accept : value : 2, time : 1539339385748
accept : value : 3, time : 1539339387749
accept : value : 4, time : 1539339389748
accept : value : 5, time : 1539339391749
Timer
Timer运算符创建一个Observable,在指定的一段时间后发出一个特定项。
Log.d(TAG, " doSomeWork time : " + System.currentTimeMillis());
Observable.timer(2, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.d(TAG, " accept : value : " + aLong + ", time : " + System.currentTimeMillis());
}
});
打印结果
doSomeWork time : 1539339766572
accept : value : 0, time : 1539339768582
Defer
在观察者订阅之前不要创建Observable,并为每个观察者创建一个新的Observable。Defer运算符等待观察者订阅它,然后它生成一个Observable,通常带有Observable工厂函数。 它为每个用户重新执行此操作,因此尽管每个用户可能认为它订阅了相同的Observable,但实际上每个用户都有自己的单独序列。
照样举个例子
public class Car {
private String brand = "QQ";
public void setBrand(String brand) {
this.brand = brand;
}
public Observable<String> brandDeferObservable() {
return Observable.defer(new Callable<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> call() {
return Observable.just(brand);
}
});
}
}
private void doSomeWork() {
Car car = new Car();
Observable<String> brandDeferObservable = car.brandDeferObservable();
car.setBrand("BMW");
// Even if we are setting the brand after creating Observable
// we will get the brand as BMW.
// If we had not used defer, we would have got QQ as the brand.
brandDeferObservable
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, " accept : value : " + s);
}
});
}
由于Defer是在观察者订阅它之后生成一个Observable,所以我们打印结果
accept : value : BMW
那如果用just来创建Observable我们看看他们打印结果的区别
public class Car {
private String brand = "QQ";
public void setBrand(String brand) {
this.brand = brand;
}
public Observable<String> brandDeferObservable() {
return Observable.just(brand);
}
}
private void doSomeWork() {
Car car = new Car();
Observable<String> brandDeferObservable = car.brandDeferObservable();
car.setBrand("BMW");
brandDeferObservable
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, " accept : value : " + s);
}
});
}
打印结果
accept : value : QQ
参考资料,参考但不局限以下链接
http://reactivex.io/documentation/operators.html#transforming