我正在调用多个Retrofit api simultanious并等待它的完成,这由Observable.zip()
正确完成。现在我想实现进步。
这是我的实施..
private void preFetchData() {
ApiInterface apiService1 = ApiClient.getWooRxClient().create(ApiInterface.class);
ApiInterface apiService2 = ApiClient.getRxClient().create(ApiInterface.class);
Map<String, String> map1 = new HashMap<>();
map1.put("on_sale", "true");
Observable<List<Product>> call1 = apiService1.getProducts1(map1)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> {
progress += 18;
Log.e("Progress1", progress + "");
mProgressBar.setProgress(progress);
mProgressBar.setProgressText(progress + "%");
});
Map<String, String> map2 = new HashMap<>();
map2.put("featured", "true");
Observable<List<Product>> call2 = apiService1.getProducts1(map2)
.subscribeOn(Schedulers.io())
.delaySubscription(100, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> {
progress += 18;
Log.e("Progress2", progress + "");
mProgressBar.setProgress(progress);
mProgressBar.setProgressText(progress + "%");
});
Map<String, String> map3 = new HashMap<>();
map3.put("page", "1");
map3.put("sort", "rating");
map3.put("per_page", "10");
Observable<List<Product>> call3 = apiService2.getCustomProducts1(map3)
.subscribeOn(Schedulers.io())
.delaySubscription(200, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> {
progress += 18;
Log.e("Progress3", progress + "");
mProgressBar.setProgress(progress);
mProgressBar.setProgressText(progress + "%");
});
Map<String, String> map4 = new HashMap<>();
map4.put("page", "1");
map4.put("sort", "popularity");
map4.put("per_page", "10");
Observable<List<Product>> call4 = apiService2.getCustomProducts1(map4)
.subscribeOn(Schedulers.io())
.delaySubscription(300, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> {
progress += 18;
Log.e("Progress4", progress + "");
mProgressBar.setProgress(progress);
mProgressBar.setProgressText(progress + "%");
});
Observable<ResponseBody> call5 = apiService2.getCurrencySymbol()
.subscribeOn(Schedulers.io())
.delaySubscription(400, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> {
progress += 10;
Log.e("Progress5", progress + "");
mProgressBar.setProgress(progress);
mProgressBar.setProgressText(progress + "%");
});
Observable<List<Category>> call6 = apiService1.getAllCategories()
.subscribeOn(Schedulers.io())
.delaySubscription(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> {
progress += 18;
Log.e("Progress6", progress + "");
mProgressBar.setProgress(progress);
mProgressBar.setProgressText(progress + "%");
});
Observable<CombinedHomePage> combined = Observable.zip(call1, call2, call3, call4, call5, call6, CombinedHomePage::new);
disposable = combined.subscribe(this::successHomePage, this::throwableError);
}
private void successHomePage(CombinedHomePage o) {
Log.e("Response", "SUCCESS " + o.featuredProductList.size());
Log.e("Response", "SUCCESS " + o.saleProductList.size());
Log.e("Response", "SUCCESS " + o.topRatedProductList.size());
Log.e("Response", "SUCCESS " + o.topSellerProductList.size());
Log.e("Response", "SUCCESS " + o.CURRENCY);
Log.e("Response", "SUCCESS " + o.categoryList.size());
}
private void throwableError(Throwable t) {
Log.e("Response", "Fail");
}
这是Logcat
首次运行
E/Progress5: 10.0
E/Progress2: 28.0
E/Progress1: 46.0
E/Progress6: 64.0
E/Progress3: 82.0
E/Response: Featured List Size 5
E/Response: Sale List Size 7
E/Response: Rated List Size 10
E/Response: Seller List Size 10
E/Response: Currency $
E/Response: Category List Size 9
第二次运行
E/Progress5: 10.0
E/Progress2: 28.0
E/Progress1: 46.0
E/Progress6: 64.0
E/Progress4: 82.0
E/Response: Featured List Size 5
E/Response: Sale List Size 7
E/Response: Rated List Size 10
E/Response: Seller List Size 10
E/Response: Currency $
E/Response: Category List Size 9
在第一次运行时,Progess 4跳过,在第二次运行时Progess 3跳过(所有Api正确完成)。
任何想法为什么会这样?
任何帮助都是适当的
答案 0 :(得分:2)
操作员按照指定的顺序订阅其来源,并在处置其他来源时,如果其中一个来源比其他来源短,则急切地完成。因此,有可能其他源永远不能运行完成(因此不会调用doOnComplete())。如果源的长度完全相同,也会发生这种情况;如果源A完成并且B已经消耗并且即将完成,则操作员检测到A将不会发送更多值并且它将立即处置B.例如:
zip(Arrays.asList(range(1, 5).doOnComplete(action1), range(6, 5).doOnComplete(action2)), (a) -> a)
将调用action1但不会调用action2。 要解决此终止属性,请使用doOnDispose(Action)或使用using()在完成或dispose()调用时进行清理。