我需要使用RxJava2在一个特定的网络调用的Disposable .subscribe方法内捕获一个UnknownHostException。
在我的一个Android应用程序中,我遇到了一个非常随机发生的错误,这使我花了很长时间才能在该字段中进行复制。我可以将其与开普敦的不可靠的网络/ SIM卡连接相关,我们在该处将应用程序部署到数百个用户。仿真器或我在德国测试过的任何电话都不会发生该错误。
当我从Wifi切换到移动数据,关闭移动数据/ wifi或进入飞行模式时,所有经典测试用例均由应用正确处理。
该应用程序多次发出API请求,并通过FCM接收数据。他们都工作正常。但是,当您打开应用程序时,有一个请求发送状态更新。暂时存在网络问题时,此请求将失败。我目前正在开普敦进行测试,这些网络问题是如此短暂和频繁,以至于Android无法以标准方式来快速处理它们,从而无法处理不可用的连接。我可以看到每周一次或两次使用数百部24/7运行的电话出现该问题。
这是引起麻烦的方法。我可以用注释掉的行来引起错误。这将使启动屏幕永久显示进度对话框。
public void sendActiveGuardStatus() {
GuardManager guardManager = GuardManager.newInstance(getBaseContext());
showProgress("Loading Operation Status");
Disposable subscription = guardManager
.setGuardAvailable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.timeout(8, TimeUnit.SECONDS)
.onErrorReturn(e -> {return null;})
.subscribe(
response -> {
// if (Math.random() < 0.5) {
// throw new UnknownHostException("Oh no, no network...");
// }
hideProgress();
startHomeActivity();
}
, throwable -> {
hideProgress();
startLoginActivity();
}
);
addSubscription(subscription);
}
这是构建请求的方式:
public class GuardManager {
public static GuardManager newInstance(Context context) {
return new GuardManager(
context,
RetrofitFactory.build(context).create(GuardNetworkService.class),
new GuardUtils()
);
}
...
public Single<SetGuardStatusResponse> setGuardAvailable() {
return networkService
.setGuardStatus("available")
.compose(response -> TokenErrorTransformer.withErrorCheck(response, context));
}
...
}
public interface GuardNetworkService {
...
@PUT("guardian/set_status_{guard_status}")
Single<SetGuardStatusResponse> setGuardStatus(@Path("guard_status") String status);
...
}
我想捕获在.subscribe(...)内部创建的异常,并在外部进行手动处理。最后,我要重试3次,两次请求之间要有延迟。
我尝试了onError()以及我能想到的所有try / catch组合,但最终总是遇到这样的异常:
2019-04-01 12:00:37.682 11683-11683/com.lionizers.guardapp W/System.err: io.reactivex.exceptions.UndeliverableException: java.net.UnknownHostException: Oh no, no network...
2019-04-01 12:00:37.682 11683-11683/com.lionizers.guardapp W/System.err: at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
2019-04-01 12:00:37.682 11683-11683/com.lionizers.guardapp W/System.err: at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:66)
我知道我可以使用RxJavaPlugins.setErrorHandler,但是我不知道如何使用该代码专门重试此单个请求。所有其他请求都通过任务/线程进行管理,因此对于代码的任何其他部分,我都不需要通用的错误处理程序。