2017-03-07 89 views
8

我遇到的問題是這樣的。我需要執行幾個請求到服務器。每個下一個請求取決於前一個的結果。 他們看起來像這樣(略):RxJava - 鏈接請求和更新UI

Observable<FileUploadResponse> obsFile = api.uploadFile(); 
Observable<TokenCreateResponse> obsCreateToken = api.createToken(); 
Observable<PaymentResponse> obsPayment = api.submitOrder(); 

我使用flatMap它返回PaymentResponse對象或發出的onError()如果一些不符合要求創建一個可觀察的。這工作正常,我可以在一次通話中完成所有請求。

問題是我無法更新這些請求之間的用戶界面。使用當前設置,我會在請求啓動時顯示加載,並在所有請求完成時將其隱藏。有沒有辦法在這些請求之間更新UI?

我想要的是: 1.文件上傳 - 在用戶界面上寫入消息。 2.創建一個令牌 - 在UI上寫一條消息。 3.提交訂單 - 在用戶界面上撰寫消息。 4.一旦完成,隱藏進度對話框。

我的理解是在每個API調用完成時使用onNext()發出一些Observable,然後在全部完成時調用onComplete()。但我該怎麼做?

+0

您可以在任何地方使用'doOnNext()'方法在處理管道,看看發生了什麼,什麼中介結果,當然觀察員和SUBCRIBE在各自的線程 – Raghunandan

+0

另一種可能性是包裝每個中間類型的常用包裝,你可以用它作爲你的Subscriber的類型。類似於'api.uploadFile()。flatMap(fileUploadResponse - > Observable.concat(Observable.just(new StatusUpdate(fileUploadResponse)),api.createToken())。flatMap(tokenCreateResponse - > Observable.concat(Observable.just(new StatusUpdate(tokenCreateResponse),api.submitOrder())...' - 一個名爲[RxSealedUnions](https://github.com/pakoito/RxSealedUnions)的庫對這種方法很有幫助... –

回答

8

你可以通過doOnNextPublishSubject來實現。首先創建一個主題和一些值:

public static final int STATUS_UPLOADING = 0; 
public static final int STATUS_TOKEN = 1; 
public static final int STATUS_SUBMITTING = 2; 
public static final int STATUS_DONE = 3; 

PublishSubject<Integer> status = PublishSubject.create(); 

public Observable<Integer> getStatusStream() { 
    return status; 
} 

然後,當你做你的上傳工作,每次的價值只發送到主題:

status.onNext(STATUS_UPLOADING); 

return api.uploadFile() 
    .doOnNext(o -> status.onNext(STATUS_TOKEN)) 
    .flatMap(o -> api.createToken()) 
    .doOnNext(o -> status.onNext(STATUS_SUBMITTING)) 
    .flatMap(o -> api.submitOrder()) 
    .doOnNext(o -> status.onNext(STATUS_DONE)) 

然後你可以訂閱Subject和更新你的UI:

model.getStatusStream() 
    .subscribeOn(AndroidSchedulers.mainThread()) 
    .subscribe(
     status -> { 
      view().setMessage(status); 
     }, 
     Throwable.printStackTrace 
    ); 

或者取決於你想如何構建您的應用程序,你可以只調用從每個doOnNext更新視圖通話 時間。您可能需要使用observeOn每次在主要的後臺線程之間切換。

+0

謝謝,這正是我在找什麼。 –