。
将其用于检索库存的详细信息。我有2种服务,一种用于获取可用库存,另一种可以为您提供给定库存的详细信息。
首先看看我的改造界面
public interface RetrofitApiService {
@GET("inv.svc/availableInventories")
Single<AvailableInventories> getAvailableInventories();
@GET("inv.svc/inventoryDetails")
Single<InventoryDetails> getInventoryDetails(@Query("invName") String invName);
}
这些是改造服务构建的对象:
AvailableInventories
List<InventoryName> inventoryNames
InventoryName
String id
String name
String ref
InventoryDetails
List<InventoryLine> inventoryLines
InventoryLine
String articleRef
String inventoryRef
String conditioning
String CountedStock
String expectedStock
所以我要调用getAvailableInventories()
,它将返回一个包含3 AvailableInventories
的InventoryName
对象(例如)首先,我想将这些inventoryNames
存储在my_ database.Inventory_names
InventoryName
String "1"
String "paris-warehouse"
String "az2r8"
InventoryName
String "2"
String "mila-warehouse"
String "d8f5s"
InventoryName
String "3"
String "berlin-warehouse"
String "g8z3d"
然后我必须打电话
getInventoryDetails("az2r8")
store in database, table inventory_line_details
getInventoryDetails("d8f5s")
store in database, table inventory_line_details
getInventoryDetails("g8z3d")
store in database, inventory_line_details
最后,我需要重定向到另一个屏幕。
我如何在RxJava中做到这一点?以前,我会使用简单的android asynctasks并使用.execute.get()
但是似乎我无法用rx java做到这一点。
我将不得不调用第一个服务,然后对每个结果使用.iterate
或.forEach
之类的东西来调用我的getInventoryDetails
服务
我很迷路。
我没有办法做这样的事情吗? :
compositeDisposable.add(simpleRetrofitService.getAvailableInventories()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(this::storeNamesToDatabse, this::logErrorAndDisplayPopup)); <-make it blocking and store AvailableInventories somewhere
for (InventoryName inventoryName : availableInventories) {
compositeDisposable.add(simpleRetrofitService.getInventoryDetails()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(this::storeDetailsToDatabse, this::logErrorAndDisplayPopup)); <-make it blocking and store InventoryDetails somewhere
}
goToNextScreen()
谢谢。
Ps:如您所见,Java 8,流和lambda对我来说是新的
根据您的情况,可以如下使用flatMap
和zip
运算符:
compositeDisposable.add(simpleRetrofitService.getAvailableInventories()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.doOnSuccess(this::storeNamesToDatabse) // store names on success
.flatMap(this::getInventoryDetails) // once availableInventories is fetched, proceed to get details
.subscribe(inventoryDetailsList -> { // we get a list of inventoryDetails
this.storeDetailsToDatabse(inventoryDetailsList); // modify your function to use list of inventory details instead
goToNextScreen(); // go to next screen when network calls finished
}, this::logErrorAndDisplayPopup))
}
getInventoryDetails(...)
返回另一个要向下游发出的Single
:
Single<List<InventoryDetails>> getInventoryDetails(AvailableInventories availableInventories) {
List<Single<InventoryDetails>> singles = new ArrayList<>();
for (InventoryName inventoryName : availableInventories) {
singles.add(
simpleRetrofitService.getInventoryDetails(inventoryName)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io()
);
}
return Single.zip(singles, inventoryDetailsList -> (List<InventoryDetails>) inventoryDetailsList); // here you might need to cast the result
}
此外,请在订阅回调中移动goToNextScreen()
呼叫以确保在离开屏幕之前一切都完成了(如上所示)。>>