RX-Android + ViewModel + Retrofit 不调用 OnComplete()
RX-Android + ViewModel + Retrofit doesn't call OnComplete()
我无法在处理完所有项目后调用 OnComplete() 方法。我需要这样做以(至少)隐藏加载视图。我对 JavaRX 有点陌生,所以我不知道问题到底出在哪里。你能帮我在处理完所有项目后调用 OnComplete() 吗?
代码执行以下操作:
- 显示加载视图并获取项目列表(仅供参考)。
- 检查它们是本地项目还是远程项目。
- 如果是本地的,获取它们并将它们添加到列表中。
- 如果它们是远程的,请下载它们并将它们添加到列表中。
- 建立列表后,在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
returns Flowable
。为了让 flowable 完成,我们需要显式处理它。
要解决,您可以将 mViewModel.getItems
转换为 return Single<List<ItemType>>
,然后使用 .flatMapObservable { Observable.fromIterable(it) }
转换流来处理每个项目。
我无法在处理完所有项目后调用 OnComplete() 方法。我需要这样做以(至少)隐藏加载视图。我对 JavaRX 有点陌生,所以我不知道问题到底出在哪里。你能帮我在处理完所有项目后调用 OnComplete() 吗?
代码执行以下操作:
- 显示加载视图并获取项目列表(仅供参考)。
- 检查它们是本地项目还是远程项目。
- 如果是本地的,获取它们并将它们添加到列表中。
- 如果它们是远程的,请下载它们并将它们添加到列表中。
- 建立列表后,在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
returns Flowable
。为了让 flowable 完成,我们需要显式处理它。
要解决,您可以将 mViewModel.getItems
转换为 return Single<List<ItemType>>
,然后使用 .flatMapObservable { Observable.fromIterable(it) }
转换流来处理每个项目。