RxJava - 如果其中一个可观察对象导致错误,如何使平面图继续?
RxJava - How to make flatmap continue if one of the observables causes an error?
我正在创建一个应用程序,它获取设备上安装的应用程序列表并从 google Play 商店检查版本更新。
这是我根据包名获取应用信息的方法:
public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
return Observable.fromIterable(apps)
.flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName));
}
如果包确实在 google Play 商店中,它工作正常,但是 returns retrofit2.adapter.rxjava2.HttpException: HTTP 404
如果找不到包名称(即:侧载应用程序)
这是我处理可观察对象的方法:
updatesViewController.getUpdates(apps)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.as(AutoDispose.autoDisposable(ViewScopeProvider.from(this)))
.subscribe(responseItem -> responseList.add(responseItem),
throwable -> responseList.add(null), //404's here, doesn't do the onComplete at all.
() -> { // onComplete
for (int i = 0; i < apps.size(); ++i) {
if (responseList.get(i) != null && apps.get(i).isLowerVersion(responseList.get(i)) {
doSomething();
}
});
如果所有应用程序都在 Play 商店中,这将按预期工作。我想做到这一点,如果在 Playstore 中 not 找不到一个或多个应用程序,它仍然可以对找到的应用程序执行 doSomething(),同时忽略找不到的应用程序't。感谢您的帮助!
当您点击其中一个 404(应用程序未在 Playstore 上注册)时,您将 null
(responseList.add(null)
) 添加到响应列表中。
那么从逻辑上讲,如果应用程序的版本较低,您就会检查并执行某些操作,这样您就可以 doSomething()
。
但是检查还会检查空值 (if (responseList.get(i) != null
[...]),因此列表中有空值,而那些不会做某事。
doSomething 是否依赖于项目中的某些数据?如果没有,你可以这样做:
if(responseList.get(i) == null || (responseList.get(i) != null && apps.get(i).isLowerVersion(responseList.get(i)))
这将为所有版本较低的应用程序或缺失的应用程序调用 doSomething(例如:导致 404 的应用程序)
请记住上面的假设,即 doSomething() 不需要来自此检索的实际数据 - 否则 doSomething()
中的后续操作将失败。
我对这个问题的解决方案:
我添加了一个 .onErrorResumeNext(Observable.empty());
可以有效地跳过导致错误的项目。
public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
return Observable.fromIterable(apps)
.flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName)
.onErrorResumeNext(Observable.empty()));
}
然后在 onComplete 中,我没有循环遍历我的所有应用程序,而是只循环遍历 responseList 中的应用程序,这主要是逻辑错误,而不是 rxJava 错误。
public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
return Observable.fromIterable(apps)
.flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName).OnErrorResumeNext(getFallbackStream()));
}
但是,您必须记住 HTTP
404
不是错误,因为 HTTP
调用成功,除非您的 HTTP
连接器映射404
到某个较低级别的 throwable
。如果没有,那么你将不得不做类似的事情:
if(404 == appInfo.getResponseCode()) {
return getFallbackStream();
}
里面 flatMap
.
我正在创建一个应用程序,它获取设备上安装的应用程序列表并从 google Play 商店检查版本更新。
这是我根据包名获取应用信息的方法:
public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
return Observable.fromIterable(apps)
.flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName));
}
如果包确实在 google Play 商店中,它工作正常,但是 returns retrofit2.adapter.rxjava2.HttpException: HTTP 404
如果找不到包名称(即:侧载应用程序)
这是我处理可观察对象的方法:
updatesViewController.getUpdates(apps)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.as(AutoDispose.autoDisposable(ViewScopeProvider.from(this)))
.subscribe(responseItem -> responseList.add(responseItem),
throwable -> responseList.add(null), //404's here, doesn't do the onComplete at all.
() -> { // onComplete
for (int i = 0; i < apps.size(); ++i) {
if (responseList.get(i) != null && apps.get(i).isLowerVersion(responseList.get(i)) {
doSomething();
}
});
如果所有应用程序都在 Play 商店中,这将按预期工作。我想做到这一点,如果在 Playstore 中 not 找不到一个或多个应用程序,它仍然可以对找到的应用程序执行 doSomething(),同时忽略找不到的应用程序't。感谢您的帮助!
当您点击其中一个 404(应用程序未在 Playstore 上注册)时,您将 null
(responseList.add(null)
) 添加到响应列表中。
那么从逻辑上讲,如果应用程序的版本较低,您就会检查并执行某些操作,这样您就可以 doSomething()
。
但是检查还会检查空值 (if (responseList.get(i) != null
[...]),因此列表中有空值,而那些不会做某事。
doSomething 是否依赖于项目中的某些数据?如果没有,你可以这样做:
if(responseList.get(i) == null || (responseList.get(i) != null && apps.get(i).isLowerVersion(responseList.get(i)))
这将为所有版本较低的应用程序或缺失的应用程序调用 doSomething(例如:导致 404 的应用程序)
请记住上面的假设,即 doSomething() 不需要来自此检索的实际数据 - 否则 doSomething()
中的后续操作将失败。
我对这个问题的解决方案:
我添加了一个 .onErrorResumeNext(Observable.empty());
可以有效地跳过导致错误的项目。
public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
return Observable.fromIterable(apps)
.flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName)
.onErrorResumeNext(Observable.empty()));
}
然后在 onComplete 中,我没有循环遍历我的所有应用程序,而是只循环遍历 responseList 中的应用程序,这主要是逻辑错误,而不是 rxJava 错误。
public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
return Observable.fromIterable(apps)
.flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName).OnErrorResumeNext(getFallbackStream()));
}
但是,您必须记住 HTTP
404
不是错误,因为 HTTP
调用成功,除非您的 HTTP
连接器映射404
到某个较低级别的 throwable
。如果没有,那么你将不得不做类似的事情:
if(404 == appInfo.getResponseCode()) {
return getFallbackStream();
}
里面 flatMap
.