
我正在尝试对按钮点击的某些 *** 作进行错误处理.对于绑定我使用RxAndroid RxAndroid.似乎它必须使用下面的代码,但它不与onBackpressure()的注释行:
CurrentUser signIn() { throw new RuntimeException();}Integer x = 1;PublishSubject<Throwable> loginingFailedSubject = PublishSubject.create();@OverrIDepublic voID onStart() { super.onStart(); RxVIEw.clicks(loginbutton) .observeOn(AndroIDSchedulers.mainThread()) .doOnNext((v) -> setLoginingWaiting()) .observeOn(Schedulers.newThread()) .map((v) -> signIn()) .lift(new SuppressErrorOperator<>(throwable -> { Log.e("mytag", "Oops, Failed " + x.toString() + " times!"); ++x; loginingFailedSubject.onNext(throwable); })) //.onBackpressureBuffer() .observeOn(AndroIDSchedulers.mainThread()) .subscribe(user -> setLoginedUser(user)); loginingFailedSubject .observeOn(AndroIDSchedulers.mainThread()) .subscribe(throwable -> setLoginingFailed(throwable));}这是SuppressErrorOperator代码:
public final class SuppressErrorOperator<T> implements Observable.Operator<T, T> { final Action1<Throwable> errorHandler; public SuppressErrorOperator(Action1<Throwable> errorHandler) { this.errorHandler = errorHandler; } public SuppressErrorOperator() {this(null);} @OverrIDe public Subscriber<? super T> call(final Subscriber<? super T> subscriber) { return new Subscriber<T>(subscriber) { @OverrIDe public voID onCompleted() { subscriber.onCompleted(); } @OverrIDe public voID one rror(Throwable e) { if (errorHandler != null) { errorHandler.call(e); } } @OverrIDe public voID onNext(T t) { subscriber.onNext(t); } }; }}这是我点击100次后在logcat中获得的内容:
哎呀,失败了16次!
它在exaclty 16次之后停止,并且在17日,它通过setLoginingWaiting()运行(我看到它,因为这个方法禁用了按钮,这也意味着,没有人可以每次请求点击超过1次.或者接近那个数字)和..这就是全部.好像它根本没有达到.lift().
但如果我取消注释.onBackpressureBuffer(),它现在完全有效!我读了很多关于背压的文章.我甚至花了一整天时间来理解Observable,Subscriber e.t.c的源代码.
我知道,16 – 是AndroID缓冲区的常量大小.但为什么会受到打击?我不经常点击按钮.此外,根本没有onNext(),所以缓冲区在任何情况下都不能超过!所有onError()都被Operator吞噬.
我也知道observeOn()通过pull协议工作,所以它内部想要使用request().如果我在.subscribe(user – > setLoginedUser(user))之前发表评论最后一次observeOn(); – 它也会起作用(但当然,这是不可接受的).
但是为什么以及什么需要onBackpressure()在这里活着?另外,为什么它会在没有任何异常的情况下死亡,例如MissingBackpressureException或类似的东西?
解决方法:
问题是您干扰了流的生命周期.映射崩溃但您禁止异常并且没有值发送到下游.如果下游没有得到任何值,它就不知道它应该请求更多,因此整个序列停止,让缓冲区填满. onBackpressureBuffer的工作原理只是因为它请求Long.MAX_VALUE并保持源运行.
但请注意,映射不应该像现在这样工作,而是取消订阅函数的第一个错误信号.
正确的选择是:
RxVIEw.clicks(loginbutton).observeOn(AndroIDSchedulers.mainThread()).doOnNext((v) -> setLoginingWaiting()).observeOn(Schedulers.newThread()).flatMap(v -> { try { return Observable.just(signIn()); } catch (Throwable ex) { Log.e("mytag", "Oops, Failed " + x.toString() + " times!"); ++x; loginingFailedSubject.onNext(ex); return Observable.empty(); } }) .observeOn(AndroIDSchedulers.mainThread()) .subscribe(user -> setLoginedUser(user)); 总结 以上是内存溢出为你收集整理的android – 为什么在这里点击事件需要onBackpressure()?全部内容,希望文章能够帮你解决android – 为什么在这里点击事件需要onBackpressure()?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)