java rx.observable_RxJava2——Observable基本用例

本文探讨了RxJava中Observable与Observer之间的事件序列,包括onComplete和onError的互斥性,以及多次调用的效果。同时,提到了在不同线程中发送和接收事件的情况,以及在被观察者速度超过观察者处理能力时可能导致的内存溢出问题,揭示了RxJava在背压处理上的局限性。
摘要由CSDN通过智能技术生成

最基本的调用

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(ObservableEmitter emitter) throws Exception {

emitter.onNext("1");

emitter.onNext("2");

emitter.onNext("3");

emitter.onNext("4");

emitter.onNext("5");

emitter.onComplete();

XLog.d("subscribe over");

}

}).subscribe(new Observer() {

@Override

public void onSubscribe(Disposable d) {

XLog.d("onSubscribe ");

}

@Override

public void onNext(String s) {

XLog.d("onNext " + s);

}

@Override

public void onError(Throwable e) {

XLog.d("onError ");

}

@Override

public void onComplete() {

XLog.d("onComplete ");

}

});

输出结果:基本按照顺序输出

onSubscribe

onNext 1

onNext 2

onNext 3

onNext 4

onNext 5

onComplete

subscribe over

onComplete/onError放中间

emitter.onNext("1");

emitter.onNext("2");

emitter.onNext("3");

//emitter.onComplete();

emitter.onError(new Exception());

emitter.onNext("4");

emitter.onNext("5");

输出结果:当中间有 onCompelete/onError 时,Observable会继续发送,但Obsever不会再接收事件了

onSubscribe

onNext 1

onNext 2

onNext 3

//onComplete

onError

subscribe over

连续两次调用onComplete

emitter.onNext("1");

emitter.onNext("2");

emitter.onNext("3");

emitter.onComplete();

emitter.onComplete();

emitter.onNext("4");

emitter.onNext("5");

输出结果:和单次调用 onComplete一样,如果放中间,Observer将不会再接收事件,且无异常

onSubscribe

onNext 1

onNext 2

onNext 3

onComplete

subscribe over

连续两次调用onError

emitter.onNext("1");

emitter.onNext("2");

emitter.onNext("3");

emitter.onError(new Exception());

emitter.onError(new Exception());

emitter.onComplete();

emitter.onNext("4");

emitter.onNext("5");

XLog.d("subscribe over");

输出结果:收到onError事件便截止

onSubscribe

onNext 1

onNext 2

onNext 3

onError

除此之外,连续 2 次调用 onError(),还报出了一个 UndeliverableException

09-22 12:45:18.181 8830-8830/www.ly.com.rxjavademo W/System.err: io.reactivex.exceptions.UndeliverableException: java.lang.Exception

at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)

at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:74)

at www.ly.com.rxjavademo.MainActivity$2.subscribe(MainActivity.java:73)

at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)

at io.reactivex.Observable.subscribe(Observable.java:12005)

at www.ly.com.rxjavademo.MainActivity.onCreate(MainActivity.java:81)

onError 和 onComplete 同时出现

emitter.onNext("1");

emitter.onNext("2");

emitter.onNext("3");

emitter.onComplete();

emitter.onError(new Exception());

emitter.onNext("4");

emitter.onNext("5");

输出结果:输出到onComplete截止

onSubscribe

onNext 1

onNext 2

onNext 3

onComplete

除此之外,同时也收到了 UndeliverableException 而终止进程

09-22 13:10:32.738 14353-14353/www.ly.com.rxjavademo W/System.err: io.reactivex.exceptions.UndeliverableException: java.lang.Exception

at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)

09-22 13:10:32.739 14353-14353/www.ly.com.rxjavademo W/System.err: at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:74)

at www.ly.com.rxjavademo.MainActivity$2.subscribe(MainActivity.java:73)

at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)

at io.reactivex.Observable.subscribe(Observable.java:12005)

at www.ly.com.rxjavademo.MainActivity.onCreate(MainActivity.java:81)

但如果把 onError 放在 onComplete 前面呢?则输出结果为:

onSubscribe

onNext 1

onNext 2

onNext 3

onError

subscribe over

说明onError 之前不能有 onComplete / onError 事件发生。

指定调度线程

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(ObservableEmitter emitter) throws Exception {

emitter.onNext("1");

emitter.onNext("2");

emitter.onNext("3");

emitter.onNext("4");

emitter.onNext("5");

XLog.d("subscribe over");

}

})

.subscribeOn(Schedulers.newThread())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer() {

@Override

public void onSubscribe(Disposable d) {

XLog.d("onSubscribe ");

}

@Override

public void onNext(String s) {

XLog.d("onNext " + s);

}

@Override

public void onError(Throwable e) {

XLog.d("onError ");

}

@Override

public void onComplete() {

XLog.d("onComplete ");

}

});

输出结果:被观察者在新的线程中执行发送事件,观察者在Android主线程中接收事件

Thread: main

onSubscribe

Thread: RxNewThreadScheduler-1

subscribe over

Thread: main

onNext 1

Thread: main

onNext 2

Thread: main

onNext 3

Thread: main

onNext 4

Thread: main

onNext 5

压力测试

被观察者限制快速发送数据,观察察者每休息 5 秒钟处理一个 onNext 事件

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(ObservableEmitter emitter) throws Exception {

int i = 0;

for (;;) {

emitter.onNext("send " + (i++));

}

}

})

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer() {

@Override

public void onSubscribe(Disposable d) {

XLog.d("onSubscribe ");

}

@Override

public void onNext(String s) {

XLog.d("onNext " + s);

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

@Override

public void onError(Throwable e) {

XLog.d("onError ");

}

@Override

public void onComplete() {

XLog.d("onComplete ");

}

});

输出结果:内存溢出!!!在RxJava2中Observable是不支持背压的

09-22 13:36:52.613 20160-20169/www.ly.com.rxjavademo W/art: Throwing OutOfMemoryError "Failed to allocate a 28 byte allocation with 1864 free bytes and 1864B until OOM; failed due to fragmentation (required continguous free 4096 bytes for a new buffer where largest contiguous free 0 bytes)" (recursive case)

总结

正常情况下事件会按照预期逐个由被观察者发送给观察者

理论上来说,onComplete 和 onError 是互斥的,我们应该控制其只发送一个

onComplete / onError 一旦发送,被观察者还会继续发送事件,但观察者将不会再接收到任何事件

onComplete 可以发送多次,以收到第一次为结束,且不会有异常

onError 只能被发送一次,并且不能在有 onComplete 之后再发送 onError ,否则会报 UndeliverableException

被观察者发送事件的速度远远超过观察者处理的速度,最终会造成 OOM。原因是 Observable 不支持背压。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值