目录
基础用法
single
Completable
Maybe
Flowable
线程调度
关键字
create
map
flatMap/concatMap
timer
interval/intervalRange
zip
concat/merge
distinct
filter
buffer
skip/skipLast
take/takeLast
debounce/ThrottleWithTimeout
last
reduce/scan
takeUntil
takeWhile
compose
RxJava github
RxAndroid github
RxJava翻译
使用步骤:
当然不要忘了根据github地址添加依赖。
private static Observable getObservable() {
return Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter observableEmitter) throws Exception {
Log.i(TAG, "subscribe: 发送 1 " + Thread.currentThread().getName());
observableEmitter.onNext(1);
Log.i(TAG, "subscribe: 发送 2 " + Thread.currentThread().getName());
observableEmitter.onNext(2);
Log.i(TAG, "subscribe: 发送 3 " + Thread.currentThread().getName());
observableEmitter.onNext(3);
Log.i(TAG, "subscribe: 发送 4 " + Thread.currentThread().getName());
observableEmitter.onNext(4);
}
});
}
public static void step1() {
// 1.初始化Obervable
Observable observable = getObservable();
// 2.初始化Observer
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable disposable) {
mDisposable = disposable;
}
@Override
public void onNext(Integer integer) {
Log.i(TAG, "onNext: 接收数据" + integer);
if (integer == 3) {
Log.i(TAG, "onNext: 主动销毁数据" + integer);
mDisposable.dispose();
}
}
@Override
public void onError(Throwable throwable) {
Log.i(TAG, "onError: 错误数据" + throwable.getMessage());
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: 完成");
}
};
// 3.创建订阅关系
observable.subscribe(observer);
}
单个数据发射器。SingleObserver只回调onSuccess和onError。
public static void single(){
Single.just(1)
.subscribe(new SingleObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(Integer integer) {
Log.i(TAG, "onSuccess: " + integer);
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError: ");
}
});
}
不发射数据,只处理 onComplete 和 onError 事件。一般配合andThen使用。
例如:提交信息到服务器,只关注成功与否,不关注数据,成功后弹出Toast。
public static void completable() {
Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
Log.i(TAG, "subscribe: 完成");
emitter.onComplete();
}
}).andThen(Observable.just(1))
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});
}
Single和Completable的结合,适用于:有可能发射数据,有可能不发射数据前的情况。调用onSucces/onComplete都会关闭流。
public static void maybe() {
Maybe.create(new MaybeOnSubscribe() {
@Override
public void subscribe(MaybeEmitter emitter) throws Exception {
// emitter.onSuccess("1");
emitter.onComplete();
}
}).subscribe(new Consumer() {
@Override
public void accept(@NonNull String s) throws Exception {
Log.i(TAG, "accept: " + s);
}
}, new Consumer() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
}
}, new Action() {
@Override
public void run() throws Exception {
Log.i(TAG, "run: complate");
}
});
}
唯一支持backpressure的Observable。类似Observable。
subscribeOn:指定被订阅数据线程,即发送数据上游线程。多次调用仅第一次有效。
observeOn:指定观察者线程,即接收数据下游线程。多次调用多次生效,根据最近一次调用调度线程。
public static void scheduler() {
Observable observable = getObservable();
observable
.subscribeOn(AndroidSchedulers.mainThread()) // 主线程发射数据
.subscribeOn(Schedulers.newThread()) // 子线程发射数据
.subscribeOn(Schedulers.io()) // io线程发射数据
.observeOn(AndroidSchedulers.mainThread()) // 主线程接收数据
.doOnNext(new Consumer() { // 在accept之前调用
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: AndroidSchedulers.mainThread() 当前线程" + Thread.currentThread().getName());
Log.i(TAG, "accept: AndroidSchedulers.mainThread() 接收数据" + integer);
}
})
.observeOn(Schedulers.io()) // io线程接收数据
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: AndroidSchedulers.io() 当前线程" + Thread.currentThread().getName());
Log.i(TAG, "accept: AndroidSchedulers.io() 接收数据" + integer);
}
});
}
doOnNext:在下游接收数据前调用。onNext()之前。
doAfterNext:在接收数据之后调用。onNext()之后。
产生一个 Obserable
被观察者对象,即上游发射器。
将发射出来的数据一一映射处理一遍。
public static void map() {
Observable observable = getObservable();
// 将 int --> String
observable.map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
return "map " + integer;
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: ==" + s);
}
});
}
将一组上游发射数据转换为N个Observable,之后无序/有序的发射这N个发射器的数据。
public static void flatMap() {
getIntObservable()
.flatMap(new Function>() {
@Override
public ObservableSource apply(Integer integer) throws Exception {
ArrayList list = new ArrayList<>();
for (int i = 0; i < integer; i++) {
list.add("第" + integer + "波数据:" + i);
}
return Observable.fromIterable(list).delay(3-integer, TimeUnit.SECONDS);
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: 接收数据 " + s);
}
});
}
定时任务。订阅后延时多久开始发射数据。
public static void timer() {
final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Log.i(TAG, "timer: 开始时间 " + dateFormat.format(System.currentTimeMillis()));
Observable.timer(2,TimeUnit.SECONDS)
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception {
Log.i(TAG, "timer: 结束时间 " + dateFormat.format(System.currentTimeMillis()));
}
});
}
计时任务。每隔一段时间发射一次数据。intervalRange有限次。
延迟1s后开始计时,每次间隔1s,5s后标记任务为处理状态。
public static void interval() {
final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Log.i(TAG, "timer: 开始时间 " + dateFormat.format(System.currentTimeMillis()));
Disposable disposable = Observable.interval(1, 1, TimeUnit.SECONDS)
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception {
Log.i(TAG, "timer: 计时 " + dateFormat.format(System.currentTimeMillis()));
}
});
try {
Thread.sleep(5000);
disposable.dispose();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
将两个或以上发射器数据合并在一起,按一一对应方式合并,所以最终结果是按照最小数量发射器,多的数据直接舍弃。从下例可以看出结果只能到 " three is 3" ,"four" 被舍弃了。
public static void zip() {
Observable.zip(getIntObservable(), getStringObservable(),
new BiFunction() {
@Override
public String apply(Integer integer, String s) throws Exception {
return s + " is " + integer;
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: " + s);
}
});
}
private static Observable getIntObservable() {
return Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter observableEmitter) throws Exception {
// Log.i(TAG, "subscribe: 发送 1 " + Thread.currentThread().getName());
observableEmitter.onNext(1);
// Log.i(TAG, "subscribe: 发送 2 " + Thread.currentThread().getName());
observableEmitter.onNext(2);
// Log.i(TAG, "subscribe: 发送 3 " + Thread.currentThread().getName());
observableEmitter.onNext(3);
// 通知下游数据发送完成 后续数据不在接收
observableEmitter.onComplete();
// Log.i(TAG, "subscribe: 发送 4 " + Thread.currentThread().getName());
observableEmitter.onNext(4);
}
});
}
private static Observable getStringObservable() {
return Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter observableEmitter) throws Exception {
observableEmitter.onNext("one");
observableEmitter.onNext("two");
observableEmitter.onNext("three");
observableEmitter.onNext("four");
// 通知下游数据发送完成 后续数据不在接收
observableEmitter.onComplete();
}
});
}
将两个上游发射器合并在一起,按照顺序依次发送数据/无序发送数据。合并的observable的数据类型必须相同。
public static void concat(){
Observable.concat(getIntObservable(),getIntObservable())
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});
}
从结果可以看concat出是在第一个observable之后有序发射第二个observable的数据。
去重,去除重复的数据。
class DistinctBean {
String name;
int id;
public DistinctBean(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return "DistinctBean{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DistinctBean)) return false;
DistinctBean that = (DistinctBean) o;
return id == that.id &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name, id);
}
}
private static Observable getDistinctObservable() {
return Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter observableEmitter) throws Exception {
observableEmitter.onNext(new DistinctBean("a", 1));
observableEmitter.onNext(new DistinctBean("b", 1));
observableEmitter.onNext(new DistinctBean("b", 1));
observableEmitter.onNext(new DistinctBean("b", 2));
// 通知下游数据发送完成 后续数据不在接收
observableEmitter.onComplete();
}
});
}
1.不指定key,直接进行对象比较,过滤掉一个数据 {b,1}
getDistinctObservable().distinct()
.subscribe(new Consumer() {
@Override
public void accept(DistinctBean distinctBean) throws Exception {
Log.i(TAG, "accept: " + distinctBean.toString());
}
});
2.指定比较的key是name字段,过滤掉后两个数据
getDistinctObservable().distinct(new Function() {
@Override
public String apply(DistinctBean distinctBean) throws Exception {
return distinctBean.name;
}
}).subscribe(new Consumer() {
@Override
public void accept(DistinctBean distinctBean) throws Exception {
Log.i(TAG, "accept: " + distinctBean.toString());
}
});
根据条件过滤掉无用数据。
public static void filter(){
getDistinctObservable().filter(new Predicate() {
@Override
public boolean test(DistinctBean distinctBean) throws Exception {
// true 通过筛选
return "b".equals(distinctBean.name);
}
}).subscribe(new Consumer() {
@Override
public void accept(DistinctBean distinctBean) throws Exception {
Log.i(TAG, "accept: " + distinctBean.toString());
}
});
}
分组截取,将上游发射器数据分组,新的发射器每次发射一组数据。
下例,每次游标滑动4,然后取后面的3个数为一个List发射。
结果为:[1,2,3] [5,6,7]
public static void buffer() {
Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
.buffer(3, 4)
.subscribe(new Consumer>() {
@Override
public void accept(List integers) throws Exception {
Log.i(TAG, "accept: " + integers.toString());
}
});
}
舍弃一些数据后开始接收数据。从前/从后
public static void skip(){
Observable.just(1,2,3,4,5)
.skipLast(2)
// .skip(2)
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});
}
只接收一定量的数据。从前/从后
public static void take(){
Observable.just(1,2,3,4,5,6)
.take(2)
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 结果 1 2
}
});
}
去抖动,覆盖掉间隔过短的数据,即有效数据为短间隔的后一个数据。
public static void debounce() {
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext(1); // 被覆盖
Thread.sleep(200);
emitter.onNext(2); // 接收
Thread.sleep(600);
emitter.onNext(3); // 被覆盖
Thread.sleep(300);
emitter.onNext(4); // 被覆盖
Thread.sleep(300);
emitter.onNext(5); // 接收
}
}).throttleWithTimeout(400, TimeUnit.MILLISECONDS)
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 结果 2 5
}
});
}
只接收最后一个数据,当没有数据时,发射传入的默认值。
public static void last() {
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onComplete();
}
}).last(3)
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 结果 3
}
});
}
将数据按照方法依次两两操作,可以设置一个初始值。
reduce只关注结果的一次数据。
scan每一步的数据都发射一次。seed也会发射一次。
public static void reduce(){
Observable.just(1,2,3,4)
.reduce(2, new BiFunction() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
return integer + integer2;
}
}).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 结果 12 scan结果:2 3 5 8 12
}
});
}
订阅并开始发射原始数据Observable,同时提供一个阀门Observable。如果阀门Observable发射了数据或者完成发送,数据Observable停止发射。
public static void takeUntil() {
// 数据Observable 200ms发射一次数据
// 阀门Observable 700ms发射数据,终止数据Observable
Observable.interval(200, TimeUnit.MILLISECONDS)
.takeUntil(Observable.timer(700, TimeUnit.MILLISECONDS))
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception {
// 结果返回数据 0 1 2
Log.i(TAG, "accept: " + aLong);
}
});
}
返回一个镜像原始Observable行为的Observable,直到某一项数据你指定的函数返回false
那一刻,这个新的Observable发射onCompleted
终止通知。
public static void takeWhile() {
Observable.just(1, 2, 3, 4, 5, 6)
.takeWhile(new Predicate() {
@Override
public boolean test(Integer i) throws Exception {
// 数据大于等于5 停止数据流
return i < 5;
}
}).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
// 返回数据 1 2 3 4
Log.i(TAG, "accept: " + integer);
}
});
}
关于Compose
结构流、拆串。
和flatMap区别:
不同之处在于它
compose()
是更高级别的抽象:它在整个流上运行,而不是单独发出的item数据。更具体的说法:
compose()
是Observable
从流中获取原始数据流的唯一方法。因此,影响整个流的操作(如subscribeOn()
和observeOn()
)需要使用compose()
。相反,如果你把
subscribeOn()
/observeOn()放在
中flatMap()
,它只会影响Observable
您创建的flatMap()
,但不是后续的流。
compose()
在创建Observable
流时立即执行,就像您已将运算符内联编写一样。flatMap()
在onNext()
每次调用它时调用它。换句话说,flatMap()
转换每个item数据,而compose()
转换整个流。
flatMap()
效率必然较低,因为Observable
每次onNext()
调用都必须创建一个新的。compose()
按原样在流上运行。如果要使用可重用代码替换某些运算符,请使用
compose()
。flatMap()
有很多用途,但这不是其中之一。
public static void compose() {
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
Log.i(TAG, "subscribe: " + Thread.currentThread().getName());
emitter.onNext(1);
}
});
Consumer consumer = new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: " + Thread.currentThread().getName());
}
};
ObservableTransformer composer = new ObservableTransformer() {
@Override
public ObservableSource apply(Observable upstream) {
return upstream.map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
Log.i(TAG, "apply: " + Thread.currentThread().getName());
return "转换数据" + integer;
}
});
}
};
observable.compose(composer)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
.subscribe(consumer);
}