-1

我正在创建一个应用程序,它获取设备上安装的应用程序列表并检查来自 google play 商店的版本更新。

这是我根据包名获取应用信息的方法:

    public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
        return Observable.fromIterable(apps)
            .flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName));
    }

如果包实际上在 google play store 上,它可以正常工作,但retrofit2.adapter.rxjava2.HttpException: HTTP 404如果找不到包名,它会返回(即:sideloaded app)

这是我处理 observables 的方法:

 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();
                          }
                     });

如果所有应用程序都在 Playstore 上,则按预期工作。我想这样做,如果在 Playstore 中找不到一个或多个应用程序它仍然可以对找到的应用程序执行 doSomething(),而忽略没有的应用程序。任何帮助表示赞赏!

4

3 回答 3

1

当您点击其中一个 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()将失败.

于 2020-01-07T00:37:38.660 回答
0

您可以使用onErrorResumeNext(..)

public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
    return Observable.fromIterable(apps)
        .flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName).OnErrorResumeNext(getFallbackStream()));
}

但是,您必须记住,这HTTP 404不是错误,因为除非您的连接器将 a 映射到某个较低级别的 a,否则会成功HTTP调用。如果没有,那么您将不得不执行以下操作:HTTP404throwable

if(404 == appInfo.getResponseCode()) {
   return getFallbackStream();
}

里面flatMap

于 2020-01-08T11:26:16.670 回答
0

我对这个问题的解决方案:

我添加了一个.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 错误。

于 2020-01-07T18:42:57.693 回答