2016-02-04 44 views
3

我正在尋找一種方法,希望使用RxJava進行一致性監控可能在不同時間觸發的多個用戶的進度。我知道如何將用戶合併到一起,或者當用戶從一種方法中解僱用戶時,我不知道如何在不同時間使用不同方法解僱用戶時採用這種方法。RxJava/Android監控器在不同時間點發射多個用戶的進度

例如,如果我有2個長時間運行的任務附加到按鈕按下。我按下按鈕1並觸發可觀察/訂閱者,通過運行的一半我按下按鈕2以觸發第二個可觀察/訂閱者。

我想在沒有任務運行時啓用按鈕,並在運行一個或多個任務時禁用它。

這可能嗎?我試圖避免設置實例變量標誌。

+0

在你的例子中,你可以先在同一個地方訂閱你的按鈕,並且可能使用類似'combineLatest'的東西來獲取它們的事件 – njzk2

回答

2

我會使用單獨的BehaviorSubjectscan來監視執行狀態。這與實例變量非常相似,但可能會激發您獲得更好的解決方案。事情是這樣的:

private final BehaviorSubject<Integer> mProgressSubject = BehaviorSubject.create(0); 

public Observable<String> firstLongRunningOperations() { 
    return Observable.just("First") 
      .doOnSubscribe(() -> mProgressSubject.onNext(1)) 
      .finallyDo(() -> mProgressSubject.onNext(-1))); 
} 

public Observable<String> secondLongRunningOperations() { 
    return Observable.just("Second") 
      .doOnSubscribe(() -> mProgressSubject.onNext(1)) 
      .finallyDo(() -> mProgressSubject.onNext(-1)); 
} 

public Observable<Boolean> isOperationInProgress() { 
    return mProgressSubject.asObservable() 
      .scan((sum, item) -> sum + item) 
      .map(sum -> sum > 0); 
} 

使用情況將是這樣的:

isOperationInProgress() 
     .subscribe(inProgress -> { 
      if (inProgress) { 
       //disable controls 
      } else { 
       //enable controls 
      } 
     }); 

通過這種方法,你可以有任意數量的長時間運行的操作,你不必解僱他們。只要不要忘記撥打doOnSubscribefinallyDo

PS。對不起,我沒有測試它,但它應該工作。

+0

將實現包裝到它自己的類中,它運行良好。謝謝! –

1

爲了使這成爲可能,讓長時間運行的操作在PublishSubject上發出onNext事件。將兩個主題與zip或combineLatest功能組合在一起並訂閱此內容。一旦組合函數接收到一個事件,這意味着兩個主體都發出了一個onNext事件,因此這兩個長時間運行操作都已完成,並且您可以啓用第三個按鈕。

private PublishSubject<Boolean> firstSubject = PublishSubject.create(); 
private PublishSubject<Boolean> secondSubject = PublishSubject.create(); 

@Override 
public void onStart() { 
    super.onStart(); 
    subscribeToResult(); 
} 

private Observable<Integer> firstOperation() { 
    return Observable.just(100) 
       .delay(1000) // takes a while 
       .subscribe(tick -> firstSubject.onNext(true)); 
} 

private Observable<Integer> firstOperation() { 
    return Observable.just(200) 
       .delay(1000) // takes a while 
       .subscribe(tick -> secondSubject.onNext(true)); 
} 

private void subscribeToResult() { 
    Observable.zip(
     firstSubject, 
     secondSubject, 
     (firstResult, secondResult) -> return true 
    ).subscribe(
     tick -> thirdButton.setEnabled(true) 
    ) 
} 

絕對看看RxJava組合函數。

+0

我喜歡這個主意。在第二個按鈕從未被推動的情況下,它還能工作嗎? –

+0

僅當所有封閉的Observable都發射了一個項目時,zip纔會發射,combineLatest將僅在每個observable至少發射一個值後纔會發射所有Observable的最新值。所以在你的情況下,第三個按鈕只能在兩個長操作完成後才能使用。 – Mauin

+0

我需要處理從不按下按鈕2的情況。基本上我希望在沒有任務運行時啓用該按鈕,並且在任務運行時禁用該按鈕。我應該在最初的問題中做得更清楚,現在就編輯它。 –

相關問題