Mvvm RX Android+ViewModel+改装不调用OnComplete()

Mvvm RX Android+ViewModel+改装不调用OnComplete(),mvvm,rx-java,retrofit2,reactive-programming,rx-android,Mvvm,Rx Java,Retrofit2,Reactive Programming,Rx Android,我无法在处理所有项后调用OnComplete方法。我需要这样做,以便至少隐藏加载视图。我对JavaRX有点陌生,所以我不知道问题到底出在哪里。您能帮我在处理所有项目时调用OnComplete吗 该代码执行以下操作: private void loadDataRX(final long fromTime, final long toTime) { mLoadingPb.setVisibility(View.VISIBLE); iCompositeDisposable.clear()

我无法在处理所有项后调用OnComplete方法。我需要这样做,以便至少隐藏加载视图。我对JavaRX有点陌生,所以我不知道问题到底出在哪里。您能帮我在处理所有项目时调用OnComplete吗

该代码执行以下操作:

private void loadDataRX(final long fromTime, final long toTime) {
    mLoadingPb.setVisibility(View.VISIBLE);
    iCompositeDisposable.clear();
    iCompositeDisposable.add(mViewModel.getItems(fromTime, toTime)
            .subscribeOn(Schedulers.io())
            .flatMap(items -> {
                Activity context = ItemFragment.this.getActivity();
                if (context == null) {
                    Log.e(TAG, "Cannot present results: context is null");
                    return Flowable.empty();
                } else {
                    context.runOnUiThread(() -> {
                        mItems.clear();
                        mCustomView.reset();
                    });
                    if (items != null && items.size() > 0) {
                        return Flowable.just(items);
                    } else {
                        Log.i(TAG, "No items.");
                        return Flowable.just(Collections.singletonList(new Item(-1))); // This is my current way of solving a similar problem so as to know if I don't have any items
                    }
                }
            })
            .concatMapIterable(items -> items)
            .concatMap(item -> {
                if (item.getUid() == -1) {
                    return Flowable.just(item);
                }
                String file = item.getFileName();
                boolean uploaded = item.isUploaded();
                if (uploaded) { // Remote file
                    if (item.getUid() > 0) {
                        return iRetrofit.create(RestApi.class).getItem(item.getUid());
                    } else {
                        return Flowable.empty();
                    }
                } else { // Local file
                    return Flowable.just(item);
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(item -> {
                Log.i(TAG, "Loaded items RX");
                if (item instanceof Item) {
                    //Do stuff with the item and the files
                } else if (item instanceof ResponseBody) {
                    //This is dirty but I didn't find another way. So here I basically extract the items and the files from the server's response. At least, it works.
                } else {
                    Log.i(TAG, "No results for the given dates");
                }
            }, throwable -> {
                mLoadingPb.setVisibility(View.GONE);
                Log.e(TAG, "Error: " + throwable.getMessage());
            }, () -> {
                mLoadingPb.setVisibility(View.GONE);
                Log.i(TAG, "Loading results completed"); // Can't get this to be called
            })
    );
}
显示加载视图并获取仅引用的项目列表。 检查它们是本地项目还是远程项目。 如果它们是本地的,则获取它们并将其添加到列表中。 如果它们是远程的,请下载它们并将其添加到列表中。 构建列表后,在UI上绘制数据。 加载视图的最终处理和隐藏。 代码如下:

private void loadDataRX(final long fromTime, final long toTime) {
    mLoadingPb.setVisibility(View.VISIBLE);
    iCompositeDisposable.clear();
    iCompositeDisposable.add(mViewModel.getItems(fromTime, toTime)
            .subscribeOn(Schedulers.io())
            .flatMap(items -> {
                Activity context = ItemFragment.this.getActivity();
                if (context == null) {
                    Log.e(TAG, "Cannot present results: context is null");
                    return Flowable.empty();
                } else {
                    context.runOnUiThread(() -> {
                        mItems.clear();
                        mCustomView.reset();
                    });
                    if (items != null && items.size() > 0) {
                        return Flowable.just(items);
                    } else {
                        Log.i(TAG, "No items.");
                        return Flowable.just(Collections.singletonList(new Item(-1))); // This is my current way of solving a similar problem so as to know if I don't have any items
                    }
                }
            })
            .concatMapIterable(items -> items)
            .concatMap(item -> {
                if (item.getUid() == -1) {
                    return Flowable.just(item);
                }
                String file = item.getFileName();
                boolean uploaded = item.isUploaded();
                if (uploaded) { // Remote file
                    if (item.getUid() > 0) {
                        return iRetrofit.create(RestApi.class).getItem(item.getUid());
                    } else {
                        return Flowable.empty();
                    }
                } else { // Local file
                    return Flowable.just(item);
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(item -> {
                Log.i(TAG, "Loaded items RX");
                if (item instanceof Item) {
                    //Do stuff with the item and the files
                } else if (item instanceof ResponseBody) {
                    //This is dirty but I didn't find another way. So here I basically extract the items and the files from the server's response. At least, it works.
                } else {
                    Log.i(TAG, "No results for the given dates");
                }
            }, throwable -> {
                mLoadingPb.setVisibility(View.GONE);
                Log.e(TAG, "Error: " + throwable.getMessage());
            }, () -> {
                mLoadingPb.setVisibility(View.GONE);
                Log.i(TAG, "Loading results completed"); // Can't get this to be called
            })
    );
}
提前感谢。

我想mViewModel.getItems会返回Flowable。为了完成flowable,我们需要显式地处理它


要解决这个问题,您可以使mViewModel.getItems返回单个,然后使用.flatMapObservable{Observable.fromIterableit}转换流来处理每个项。

Hmmm您能再详细说明一下吗?的确,它返回一个可流动的,但根据文档,Single也不会触发onComplete…是的,Single将在成功时触发,可以使用它来代替onComplete。Flowable适用于订阅流并侦听(例如)数据库中的更改。若您只需要在后台线程中检索一些数据一次,那个么单个线程将满足您的需要。