RxJava3 & RxAndroid3
基本概念
引入依赖
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
基本概率
角色 | 说明2 |
---|---|
Observable | 被观察者 |
Observer | 观察者 |
Subscribe | 订阅 |
Disposable | 断连 |
在 RxJava3有以下几个基类
- io.reactivex.Flowable:发送0个N个的数据,支持Reactive-Streams和背压
- io.reactivex.Observable:发送0个N个的数据,不支持背压,
- io.reactivex.Single:只能发送单个数据或者一个错误
- io.reactivex.Completable:没有发送任何数据,但只处理 onComplete 和 onError 事件。
- io.reactivex.Maybe:能够发射0或者1个数据,要么成功,要么失败。
Consumer和Observer区别
Consumer是简易版Observer,不会接收onError()和onCompete()
Observable.just(1,2,3,4,5,6)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e("TAG", "accept: " + integer);
}
});
Observable.just(1, 2, 3, 4, 5, 6)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e("TAG", "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("TAG", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete: ");
}
});
创建操作符
observeOn
指定观察者的线程,如在Android中访问网络后,数据需要在主线程中处理,这时需要使用observeOn()
将观察者的线程切换为主线程。
subcribeOn
指定被观察者的线程,如在Android中访问网络,这时需要使用subcribeOn()
将被观察者的线程切换为子线程
doOnNext
每次调用onNext()
之前都会回调该方法
doOnError
每次调用onError()
之前都会回调该方法
doOnComplete
每次调用onComplete()
之前都会回调该方法
延迟操作符
defer 延迟创建
延迟创建被观察者,只有当订阅时才会创建被观察者
Integer flag = 1;
Observable<Integer> just = Observable.just(flag);
Observable<Integer> observable = Observable.defer(() -> just);
flag = 100;
observable.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
timer 延迟执行
Observable.timer(10, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Throwable {
Log.e(TAG, "accept: " + aLong);
}
});
interval 间隔发射数据
Observable.interval(3, 1, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Throwable {
Log.e(TAG, "accept: " + aLong);
}
});
0
1
2
3
4
5
6
7
delay
被观察者延迟发射数据
Observable.just(1, 2, 3)
.delay(3, TimeUnit.SECONDS)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
2
3
过滤操作符
对数据源进行选择或过滤的操作
skip 跳过
跳过前几个:
Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
.skip(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
4
5
6
7
8
跳过后几个:
Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
.skipLast(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
2
3
4
5
distinct 去重
去除重复数据
Observable.just(1, 2, 3, 4, 1, 2, 3)
.distinct()
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
2
3
4
filter 过滤
返回指定数据
Observable.just(1, 2, 3, 4, 5, 6)
.filter(x -> x % 2 == 0)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
2
4
6
first last
first发射第一个数据,如果没有则发送默认值;
last发射最后一个数据,如果没有则发送默认值
Observable.just(1, 2, 3, 4, 5)
.first(0)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
Observable.just(1, 2, 3, 4, 5)
.last(100)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
5
take
发射前几个数据
Observable.just(1, 2, 3, 4, 5, 6)
.take(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
2
3
onType 过滤类型
过滤指定类型
Observable.just(1, "A", 'c', 1.1f, 2.22, 500L, 9)
.ofType(Integer.class)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
9
debounce 去抖动
用于防止频繁点击等操作,在规定时间内,用户重复操作只有最后一次有效
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws InterruptedException {
emitter.onNext("A");
Thread.sleep(2000);
emitter.onNext("B");
Thread.sleep(200);
emitter.onNext("C");
Thread.sleep(500);
emitter.onNext("D");
Thread.sleep(2000);
emitter.onNext("E");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io())
.debounce(1, TimeUnit.SECONDS)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) {
Log.e(TAG, "accept: " + s);
}
});
A
D
E
sample
在一定周期内发射最新数据
与debounce区别,sample是以时间为周期的发射,周期内取最新数据,debounce是以最后一个有效数据开始的
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
Thread.sleep(200);
emitter.onNext("B");
Thread.sleep(500);
emitter.onNext("C");
Thread.sleep(600);
emitter.onNext("D");
Thread.sleep(700);
emitter.onNext("E");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io())
.sample(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
C
D
throttleFirst
和sample()类似,但是指定的是周期内的第一个数据
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
Thread.sleep(200);
emitter.onNext("B");
Thread.sleep(500);
emitter.onNext("C");
Thread.sleep(600);
emitter.onNext("D");
Thread.sleep(700);
emitter.onNext("E");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io())
.throttleFirst(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
time 超时
后一个数据发射未在前一个元素发射后规定时间内发射则抛出超时异常。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
Thread.sleep(400);
emitter.onNext("B");
Thread.sleep(1500);
emitter.onNext("C");
Thread.sleep(600);
emitter.onNext("D");
emitter.onComplete();
}
}).timeout(1, TimeUnit.SECONDS)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
A
B
Caused by: java.util.concurrent.TimeoutException
连接操作符
startWith
将指定数据源合并到其他数据源的头部
Observable<String> first = Observable.just("A", "B", "C");
Observable<String> second = Observable.just("1", "2", "3");
second.startWith(first)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
A
B
C
1
2
3
concat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jzm8rRFT-1595822035716)(https://fernandocejas.com/assets/images/concat_vs_flatmap_05.png)]
组合数据源,组合后按顺序发射
Observable<String> first = Observable.just("A", "B", "C");
Observable<String> second = Observable.just("1", "2", "3");
Observable.concat(first, second)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
A
B
C
1
2
3
merge
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTls5J8V-1595822035718)(https://fernandocejas.com/assets/images/concat_vs_flatmap_04.png)]
合并数据源,并行执行
与concat
区别:concat
是按顺序执行,merge
是按时间并行执行
Observable<String> first = Observable.just("A", "B", "C");
Observable<String> second = Observable.just("1", "2", "3");
Observable.merge(first, second)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
A
B
C
1
2
3
zip
合并多个数据源里的元素
Observable<String> first = Observable.just("A", "B", "C");
Observable<String> second = Observable.just("1", "2", "3", "4");
Observable.zip(first, second, new BiFunction<String, String, String>() {
@Override
public String apply(String s, String s2) throws Throwable {
return s + "-" + s2;
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
A-1
B-2
C-3
变化操作符
buffer
将数据源拆分为长度为n的list集合
Observable.range(0, 10)
.buffer(4)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Throwable {
Log.e(TAG, "accept: " + integers);
}
});
[0, 1, 2, 3]
[4, 5, 6, 7]
[8, 9]
cast
将数据源里的元素转换为指定类型,转换失败抛出异常
Observable.just(1, 5, 9, 2.2, 3.3f, '3')
.cast(Integer.class)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
1
5
9
Caused by: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
map
将数据源里的数据按照指定方法进行变化
Observable.just(1, 2, 3, 4, 5)
.map(new Function<Integer, Integer>() {
@Override
public Integer apply(Integer integer) throws Throwable {
return integer * 2;
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG, "accept: " + integer);
}
});
2
4
6
8
10
flatMap
将数据源里的每个元素拆分,并转换为新的数据源,然后在组合在一起发射,所以flatMap
发射出的数据是无序的
Observable.just(1, 2, 3)
.flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Throwable {
ArrayList<String> list = new ArrayList();
for (int i = 0; i < 3; i++) {
list.add(String.format("key:%d, value=%d", integer, i));
Thread.sleep(500);
}
return Observable.fromIterable(list).delay(1, TimeUnit.MILLISECONDS);
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
key:A value=0
key:B value=0
key:C value=0
key:A value=1
key:C value=1
key:B value=1
key:A value=2
key:C value=2
key:B value=2
concatMap
将数据源里的数据拆分并生成新的数据源,并有序的组合在一起,发射数据,所以concatMap
是有序的
有序
Observable.just("A", "B", "C")
.concatMap(new Function<String, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(String s) throws Throwable {
return Observable.intervalRange(0, 3, 0, 1, TimeUnit.SECONDS)
.map(new Function<Long, String>() {
@Override
public String apply(Long aLong) throws Throwable {
return String.format("key:%s value=%d", s, aLong);
}
});
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG, "accept: " + s);
}
});
key:A value=0
key:A value=1
key:A value=2
key:B value=0
key:B value=1
key:B value=2
key:C value=0
key:C value=1
key:C value=2
groupBy
对数据源进行分组
Observable.just("Tiger", "Elephant", "Cat", "Chameleon", "Frog", "Fish", "Turtle", "Flamingo")
.groupBy(new Function<String, Character>() {
@Override
public Character apply(String s) throws Throwable {
return s.charAt(0);
}
}, new Function<String, String>() {
@Override
public String apply(String s) throws Throwable {
return s.toUpperCase();
}
})
.concatMapSingle(new Function<GroupedObservable<Character, String>, SingleSource<List<String>>>() {
@Override
public SingleSource<List<String>> apply(GroupedObservable<Character, String> characterStringGroupedObservable) throws Throwable {
// Log.e(TAG, "key: " + characterStringGroupedObservable.getKey());
return characterStringGroupedObservable.toList();
}
})
.subscribe(new Consumer<List<String>>() {
@Override
public void accept(List<String> strings) throws Throwable {
Log.e(TAG, "accept: " + strings);
}
});
[TIGER, TURTLE]
[ELEPHANT]
[CAT]
[CHAMELEON]
[FROG]
[FISH]
[FLAMINGO]
scan
聚合操作
Observable.just(1, 2, 3, 4, 5)
.scan(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
Log.e(TAG, "accept: " + integer);
}
});
1
3
6
10
15
处理内存泄露
CompositeDisposable
private final CompositeDisposable disposables = new CompositeDisposable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
disposables.add(Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose(() -> Log.e(TAG, "Disposing subscription from onCreate()"))
.subscribe(num -> Log.e(TAG, "Started in onCreate(), running until onDestroy(): " + num))
);
}
@Override
protected void onDestroy() {
super.onDestroy();
disposables.clear();
}
AutoDispose
implementation 'com.uber.autodispose2:autodispose:2.0.0'
implementation 'com.uber.autodispose2:autodispose-android:2.0.0'
implementation 'com.uber.autodispose2:autodispose-lifecycle:2.0.0'
implementation 'com.uber.autodispose2:autodispose-androidx-lifecycle:2.0.0'
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose(() -> Log.e(TAG, "Disposing subscription from onCreate()"))
.to(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
.subscribe(num -> Log.e(TAG, "Started in onCreate(), running until onDestroy(): " + num));
https://juejin.im/post/5d1eeffe6fb9a07f0870b4e8#heading-46