在rxjava 1中 如果你订阅的时候,没有传入onEror的处理。默认给你一个InternalObservableUtils.ERROR_NOT_IMPLEMENTED。
而这个ERROR_NOT_IMPLEMENTED的实现就是抛出这个异常。
于是你经常会收到这个崩溃的报告。
关键在于这个错误不一定是你的代码引入的,只要任何使用rxjava1的库,没有自己处理好错误,错误就会被抛出,最后APP就崩溃了。对于一些项目,更换第三方库的代价太大。我们能不能拦截这个error的抛出呢。其实是可以的,关键就是这个ERROR_NOT_IMPLEMENTED 。我们可以通过反射去设置它,让它不抛出错误。比如这样。
public class RxJava1Util {
public static void setErrorNotImplementedHandler() {
try {
Field field = InternalObservableUtils.class.getDeclaredField("ERROR_NOT_IMPLEMENTED");
//将字段的访问权限设为true:即去除private修饰符的影响
field.setAccessible(true);
/*去除final修饰符的影响,将字段设为可修改的*/
Field modifiers = field.getClass().getDeclaredField("accessFlags");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
Log.e("zzz", "捕获异常:" + throwable.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public static void testError(){
Observable.just("123")
.map(a -> {
String i = null;
i.length();
return 1;
}).subscribe();
}
}
只需要在Application的onCreate()方法中调用就行了。
@Override
public void onCreate() {
super.onCreate();
RxJava1Util.setErrorNotImplementedHandler();
}
在RXJava 2中可以通过 RxJavaPlugins类的setErrorHandler方法就可以拦截无人处理的错误,自行处理。
/**
* Sets the specific hook function.
* @param handler the hook function to set, null allowed
*/
public static void setErrorHandler(@Nullable Consumer<? super Throwable> handler) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
errorHandler = handler;
}
Rxjava1也有RxJavaErrorHandler,不过它不能改变error的传播流程。只能用来观察发生的错误。