2016-02-04 5 views
3

Я ищу способ, надеюсь, используя RxJava для согласованности, отслеживать ход нескольких подписчиков, которые могут быть запущены в разное время. Я знаю, как объединить подписчиков или flatMap вместе, когда они все уволены из одного метода, но я не знаю, как это сделать, когда их увольняют в разное время из разных методов.RxJava/Android отслеживает прогресс нескольких подписчиков, запущенных в разное время

Например, если у меня есть две длительные задачи, связанные с нажатиями кнопок. Я нажимаю кнопку 1 и выключаю наблюдаемый/абонент, на полпути через запуск. Я нажимаю кнопку 2, чтобы отключить второй наблюдаемый/абонент.

Я хочу включить кнопку, когда никакие задачи не выполняются и не отключать ее при выполнении одной или нескольких задач.

Возможно ли это? Я также пытаюсь избежать установки флажков переменных экземпляра.

+0

в вашем примере, вы можете начать подписку на обе кнопки в одном и том же месте и, возможно, использовать что-то вроде 'combLatest', чтобы получить из них событие – njzk2

ответ

2

Я бы использовал отдельный BehaviorSubject и scan для контроля состояния выполнения. Это очень похоже на переменную экземпляра, но, вероятно, это может вдохновить вас на лучшее решение. Что-то вроде этого:

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 
      } 
     }); 

При таком подходе вы можете иметь любое количество длительной эксплуатации ходовой, и вы не должны их всех стрелять. Не забудьте позвонить по телефону doOnSubscribe и finallyDo.

PS. Извините, я не тестировал его, но он должен работать.

+0

Обернуло внедрение в свой класс, и оно хорошо работало. Благодаря! –

1

Чтобы сделать это возможным, пусть обе продолжительные операции испускают событие onNext в PublishSubject. Объедините обе темы с функцией zip или combLatest и подписаться на это. Как только функция комбайна получает событие, это означает, что оба объекта выбрали событие 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

zip будет выдаваться только в том случае, если все закрытые Observables испускали элемент, а combLatest также будет испускать только последнее значение всех наблюдаемых после того, как каждое наблюдаемое имеет хотя бы одно значение. Таким образом, в вашем случае, 3-я кнопка будет включена только после завершения обеих длинных операций. – Mauin

+0

Мне нужно обработать случай, когда кнопка 2 никогда не толкается. В основном я хочу, чтобы кнопка включалась, когда никакие задачи не выполнялись и не были отключены при запуске задач. Я должен был сделать это более ясным в своем первоначальном вопросе, отредактирую его сейчас. –

Смежные вопросы