【我的Android进阶之旅】 RxJava 理解Backpressure并解决异常 rx.exceptions.MissingBackpressureException
今天测试人员在测试应用APP的时候应用crash了,查看了下crash log如下所示:
java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:112)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: rx.exceptions.OnErrorNotImplementedException
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:276)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:219)
at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107)
... 7 more
Caused by: rx.exceptions.MissingBackpressureException
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.onNext(OperatorObserveOn.java:162)
at rx.internal.operators.OnSubscribeTimerPeriodically$1.call(OnSubscribeTimerPeriodically.java:52)
at rx.Scheduler$Worker$1.call(Scheduler.java:134)
at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$2.call(EventLoopsScheduler.java:187)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
rx.exceptions.OnErrorNotImplementedException
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:276)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:219)
at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: rx.exceptions.MissingBackpressureException
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.onNext(OperatorObserveOn.java:162)
at rx.internal.operators.OnSubscribeTimerPeriodically$1.call(OnSubscribeTimerPeriodically.java:52)
at rx.Scheduler$Worker$1.call(Scheduler.java:134)
at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$2.call(EventLoopsScheduler.java:187)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
rx.exceptions.MissingBackpressureException
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.onNext(OperatorObserveOn.java:162)
at rx.internal.operators.OnSubscribeTimerPeriodically$1.call(OnSubscribeTimerPeriodically.java:52)
at rx.Scheduler$Worker$1.call(Scheduler.java:134)
at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$2.call(EventLoopsScheduler.java:187)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
查看MissingBackpressureException异常类的源代码如下描述:
/**
* Copyright 2014 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rx.exceptions;
/**
* Represents an exception that indicates that a Subscriber or operator attempted to apply reactive pull
* backpressure to an Observable that does not implement it.
* <p>
* If an Observable has not been written to support reactive pull backpressure (such support is not a
* requirement for Observables), you can apply one of the following operators to it, each of which forces a
* simple form of backpressure behavior:
* <dl>
* <dt><code>onBackpressureBuffer</code></dt>
* <dd>maintains a buffer of all emissions from the source Observable and emits them to downstream Subscribers
* according to the requests they generate</dd>
* <dt><code>onBackpressureDrop</code></dt>
* <dd>drops emissions from the source Observable unless there is a pending request from a downstream
* Subscriber, in which case it will emit enough items to fulfill the request</dd>
* </dl>
* If you do not apply either of these operators to an Observable that does not support backpressure, and if
* either you as the Subscriber or some operator between you and the Observable attempts to apply reactive pull
* backpressure, you will encounter a {@code MissingBackpressureException} which you will be notified of via
* your {@code onError} callback.
* <p>
* There are, however, other options. You can throttle an over-producing Observable with operators like
* {@code sample}/{@code throttleLast}, {@code throttleFirst}, or {@code throttleWithTimeout}/{@code debounce}.
* You can also take the large number of items emitted by an over-producing Observable and package them into
* a smaller set of emissions by using operators like {@code buffer} and {@code window}.
* <p>
* For a more complete discussion of the options available to you for dealing with issues related to
* backpressure and flow control in RxJava, see
* <a href="https://github.com/ReactiveX/RxJava/wiki/Backpressure">RxJava wiki: Backpressure</a>.
*/
public class MissingBackpressureException extends Exception {
private static final long serialVersionUID = 7250870679677032194L;
/**
* Constructs the exception without any custom message.
*/
public MissingBackpressureException() {
}
/**
* Constructs the exception with the given customized message.
* @param message the customized message
*/
public MissingBackpressureException(String message) {
super(message);
}
}
如上面文字描述,抛出MissingBackpressureException往往就是因为,被观察者发送事件的速度太快,而观察者处理太慢,而且你还没有做相应措施,所以报异常。
onBackpressurebuffer:
把observable发送出来的事件做缓存,当request方法被调用的时候,给下层流发送一个item(如果给这个缓存区设置了大小,那么超过了这个大小就会抛出异常)。
onBackpressureDrop:
将observable发送的事件抛弃掉,直到subscriber再次调用request(n)方法的时候,就发送给它这之后的n个事件。
下面参考了几篇博客之后,理解了Backpressure的概念,并解决了rx.exceptions.MissingBackpressureException异常,读者也可以参考以下几篇博客之后,自己根据自己实际情况来选择不同的解决方式来解决该异常。
参考链接如下:
关于RxJava最友好的文章——背压(Backpressure)
https://zhuanlan.zhihu.com/p/24473022?refer=dreawerRxJava 并发之数据流发射太快如何办(背压(Backpressure))
http://blog.csdn.net/jdsjlzx/article/details/51868640- RxJava 2.0中backpressure(背压)概念的理解
http://blog.csdn.net/jdsjlzx/article/details/52717636- RxJava 驯服数据流之 hot & cold Observable
http://blog.csdn.net/jdsjlzx/article/details/51839090- RxJava 教程第四部分:并发 之数据流发射太快如何办
http://blog.chengyunfeng.com/?p=981&utm_source=tuicool&utm_medium=referral- http://reactivex.io/RxJava/javadoc/rx/exceptions/MissingBackpressureException.html
Backpressure
https://github.com/ReactiveX/RxJava/wiki/BackpressureJava Code Examples for rx.exceptions.MissingBackpressureException
http://www.programcreek.com/java-api-examples/index.php?api=rx.exceptions.MissingBackpressureException
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址: http://blog.csdn.net/ouyang_peng/article/details/66978253
【我的Android进阶之旅】 RxJava 理解Backpressure并解决异常 rx.exceptions.MissingBackpressureException的更多相关文章
- 我的Android进阶之旅------>RxJava学习资料汇总
在响应式编程中,应该牢记以下两点: everything is a stream(一切皆流) don't break the chain(不要打断链式结构) 记住,可观测序列就像一条河,它们是流动的. ...
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包括图像的文本信息).并简要说明实现方法. 答案:Android SDK支持例如以下显示富文本信息的方式. 1.使用T ...
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用Tex ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之游戏效果预览(一)
今天看完了李刚老师的<疯狂Android讲义>一书中的第18章<疯狂连连看>,从而学会了如何编写一个简单的Android疯狂连连看游戏. 开发这个流行的小游戏,难度适中,而且能 ...
- 我的Android进阶之旅------>HTTP Header 详解
HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务器给与响应.就整个网络资源传 ...
- [置顶] 我的Android进阶之旅------>介绍一款集录制与剪辑为一体的屏幕GIF 动画制作工具 GifCam
由于上一篇文章:我的Android进阶之旅------>Android之动画之Frame Animation实例 中展示的是Frame动画效果,但是之前我是将图片截取下来,不好说明确切的动画过程 ...
- 【我的Android进阶之旅】推荐一款视频转换GIF图片格式的转换工具(Video to GIF)
一.背景 最近想把一些Android Demo的运行效果图获取下来,但是一直使用真机进行调试,在电脑上不好截取一段gif动画.而之前使用模拟器的时候可以使用 GifCam 工具进行屏幕动画截取.Gif ...
- 我的Android进阶之旅------>Android字符串资源中的单引號问题error: Apostrophe not preceded by 的解决的方法
刚刚在string字符串资源文件里,写了一个单引號.报错了,错误代码例如以下 error: Apostrophe not preceded by \ (in OuyangPeng's blog ) 资 ...
- 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比和十六进制对应关系以及计算方法
我的Android进阶之旅-->Android颜色值(RGB)所支持的四种常见形式 透明度百分比和十六进制对应关系表格 透明度 十六进制 100% FF 99% FC 98% FA 97% F7 ...
随机推荐
- Android WebView的注意事项
1.修改权限,添加<uses-permission android:name="android.permission.INTERNET"/> 2.loadUrl方法要写 ...
- C基础之移位操作
因为左移操作不会导致符号位出现缺位,所以不考虑符号位,低位补0即可:右移操作会涉及到符号位出现缺位的问题,所以在有符号数的右移操作时要考虑符号位怎么补的问题. 左移操作(<<)对于无符号数 ...
- 网卡优化RPS/RFS
网卡优化 RSS receive side scaling,网卡多队列,需要硬件支持.网卡接收到网络数据包后,要发送一个硬件中断,通知CPU取数据包.默认配置,都是由CPU0去做. RPS recei ...
- Ubuntu下安装SSH服务
判断是否安装ssh服务,可以通过如下命令进行: $ ssh localhost ssh: connect to host localhost port 22: Connection refused 如 ...
- VS Code直接调试Angular代码
安装VS Code扩展 安装Debugger for Chrome 安装Debugger for Firefox 配置Launch.json文件 Launch.json文件的创建和生成我们可以利用VS ...
- PHP多进程编程(2):管道通信
一个进程如果是个人英雄主义,那么多进程就是集体主义.(不严格区分多进程 和 多线程的差别) 你不再是一个独行侠,而是一个指挥家. 独来独往,非常自由自在,但是,很多时候,不如众人拾柴火焰高. 这就是我 ...
- OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言,使页面更简洁;
OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言,使页面更简洁: 支持运算符(如+-*/),比普通的标志具有更高的自由度和更强的功能 ...
- scanner, BufferedReader, InputStreamReader 区别及特殊字符的输入
1. Scanner是一个可以使用正则表达式来分析基本类型和字符串的简单文本扫描器!也就是控制台应用程序最为常用的文本输入方式!Scanner取得输入数据的依据是空格符:如按下空格键,Tab键或者En ...
- 使用ADO GetChunk/AppendChunk 数据库存取二进制文件图象
在设计数据库的过程中,我们会经常要存储一些图形.长文本.多媒体(视频.音频文件)等各种各样的程序文件,如果我们在数据库中仅存储这些文件的路径信息,尽管这可以大大地减小数据库的大小,但是由于文件存在磁盘 ...
- 深入理解JS之Scope链
JS被很多人认为是『拙劣的语言』,被这门语言里的各种离奇的事情整的团团转,这篇文章主要来讲讲JS中的Scope链,其主要是影响JS中的变量作用域. 注:本文适合稍有一定JS基础的同学 目录: 初步认识 ...