Подтвердить что ты не робот

Android Rxjava подписаться на изменение переменной

Я изучаю шаблон Observer, я хочу, чтобы моя наблюдаемая отслеживала определенную переменную, когда она меняет ее значение и выполняет некоторые операции, я сделал что-то вроде:

public class Test extends MyChildActivity {

   private int VARIABLE_TO_OBSERVE = 0;

   Observable<Integer> mObservable = Observable.just(VARIABLE_TO_OBSERVE);  

   protected void onCreate() {/*onCreate method*/
       super();
       setContentView();
       method();
       changeVariable();
   }

   public void changeVariable() {
       VARIABLE_TO_OBSERVE = 1;
   }

   public void method() {
       mObservable.map(value -> {
            if (value == 1) doMethod2();
            return String.valueOf(value);
       }).subScribe(string -> System.out.println(string));
   }

   public void doMethod2() {/*Do additional operations*/}

}

Но doMethod2() не получает вызов

4b9b3361

Ответ 1

В жизни нет ничего волшебного: если вы обновите значение, ваш Observable не будет уведомлен. Вы должны сделать это сами. Например, используя PublishSubject.

public class Test extends MyChildActivity {

    private int VARIABLE_TO_OBSERVE = 0;

    Subject<Integer> mObservable = PublishSubject.create();  

   protected void onCreate() {/*onCreate method*/
        super();
        setContentView();
        method();
        changeVariable();
    }

    public void changeVariable() {
        VARIABLE_TO_OBSERVE = 1;
        // notify the Observable that the value just change
        mObservable.onNext(VARIABLE_TO_OBSERVE);
    }

   public void method() {
       mObservable.map(value -> {
           if (value == 1) doMethod2();
           return String.valueOf(value);
       }).subScribe(string -> System.out.println(string));
   }

   public void doMethod2() {/*Do additional operations*/}

 }

Ответ 2

@dwursteisen Ничто не является магии, нет, но я думаю, что мы можем получить немного больше магии, чем это... 😊

Как насчет использования Rx BehaviourSubject следующим образом:

import rx.functions.Action1;
import rx.subjects.BehaviorSubject;    

public class BehaviourSubjectExample {

    public BehaviourSubjectExample() {
        subject.skip(1).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("The value changed to " + integer );
            }
        });
    }

    public final BehaviorSubject<Integer> subject = BehaviorSubject.create(0);

    public int  getValue()          { return subject.getValue(); }
    public void setValue(int value) { subject.onNext(value);     }
}

Удалите .skip(1), если вы хотите, чтобы код наблюдения отображал начальное значение.

Поддержка переменных остается с BehaviourSubject и может быть доступна через обычный Java Getter/Setter. Это, конечно же, игрушечный пример: если бы ваш случай использования был действительно таким простым, не было бы оправдания не только написанию:

private int value = 0;

public int  getValue() { return value; }
public void setValue(int value) {
    this.value = value;
    System.out.println("The value changed to " + value );
}

... но использование BehaviourSubject позволяет вам переместить изменения в другие потоки данных Rx внутри вашего класса для составления более продвинутых действий.