我有一个创建类似下面的发射器的方法,在改装回调中调用onError会出现问题(可能是正常行为)。尝试调用onError时,我得到了UndeliverableException。
我可以通过检查subscriber.isDiposed()来解决这个问题,我想知道如何调用onError coz我需要通知我的UI级别。
- 加法1
--> RxJava2CallAdapterFactoryalready implemented private static Retrofit.Builder builderSwift = new Retrofit.Builder() .baseUrl(URL_SWIFT) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(new ToStringConverterFactory()); --> When i added below code to application class app won't crash --> but i get java.lang.exception instead of my custom exception RxJavaPlugins.setErrorHandler(Functions<Throwable>emptyConsumer()); @Override public void onFileUploadError(Throwable e) { Log.d(TAG, "onFileUploadError: " + e.getMessage()); }
public Observable<UploadResponseBean> upload(final UploadRequestBean uploadRequestBean, final File file) {
return Observable.create(new ObservableOnSubscribe<UploadResponseBean>() {
@Override
public void subscribe(@NonNull final ObservableEmitter<UploadResponseBean> subscriber) throws Exception {
// ---> There are no problem with subscriber while calling onError
// ---> Retrofit2 service request
ftsService.upload(token, uploadRequestBean, body).enqueue(new Callback<UploadResponseBean>() {
@Override
public void onResponse(Call<UploadResponseBean> call, Response<UploadResponseBean> response) {
if (response.code() == 200){
// ---> calling onNext works properly
subscriber.onNext(new UploadResponseBean(response.body().getUrl()));
}
else{
// ---> calling onError throws UndeliverableException
subscriber.onError(new NetworkConnectionException(response.message()));
}
}
@Override
public void onFailure(Call call, Throwable t) {
subscriber.onError(new NetworkConnectionException(t.getMessage()));
}
});
}
});
}
答案 0 :(得分:8)
由于版本2.1.1 func (c App) Index() revel.Result {
dat := c.Params.Get(sendIt);
return c.Render(dat)
}
可用:
现在发射器API(例如FlowableEmitter,SingleEmitter等) 提供了一个新方法tryOnError尝试发出Throwable if 序列未被取消/处置。与常规onError不同,if 下游不再愿意接受事件,方法 返回false并且没有发出UndeliverableException信号。
答案 1 :(得分:7)
问题就像你说你需要检查Subscriber
是否已经处理掉了,因为RxJava2对Subscriber
已经处理过后引发的错误更加严格。
RxJava2将此类错误传递给RxJavaPlugins.onError
,默认情况下打印到堆栈跟踪并调用线程未捕获的异常处理程序。你可以阅读完整的解释here。
现在发生的事情是,您可能在查询完成并发送错误之前从此Observable
取消订阅(处置),因此您获得了UndeliverableException
。
我想知道如何调用onError coz我需要通知我的UI级别。
因为这是在你的用户界面取消订阅后发生的,所以用户界面不应该关心。在正常流程中,这个错误应该正确传递。
关于您的实施的一些一般性观点:
onError
也会出现同样的问题。Subscriber
取消订阅,请求仍会继续。ObservableEmitter.setCancellable()
/ setDisposable()
),如果您在请求完成之前取消订阅,您仍会遇到此问题 - 这将导致取消和您的{ {1}}逻辑将调用onFailure
,同样的问题也会发生。onError()
将不会使Scheduler
线程上的实际请求发生,而只会发生订阅。您可以使用Scheduler
和Retrofit阻止调用Observable.fromCallable
来获得对实际发生的线程调用的更多控制。总结一下 -
在这种情况下,使用execute
保护onError()
的来电是一种很好的做法
但我认为最好的做法是使用Retrofit RxJava调用适配器,这样你就可以进行改造调用ObservableEmitter.isDiposed()
,并且已经考虑了所有这些因素。
答案 2 :(得分:0)
我发现此问题是由在Fragment中检索视图模型时使用不正确的上下文引起的:
ViewModelProviders.of(requireActivity(), myViewModelFactory).get(MyViewModel.class);
因此,视图模型位于活动的上下文中,而不是片段。将其更改为以下代码可解决此问题。
ViewModelProviders.of(this, myViewModelFactory).get(MyViewModel.class);