2016-08-03 3 views
13

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

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() не назовешь

+0

Я давно покинул Java. Вот моя мысль. Потому что 'VARIABLE_TO_OBSERVE' копируется в Observable. Следовательно, этого не наблюдается. Как насчет 'private Integer VARIABLE_TO_OBSERVE = 0;'? – Danh

ответ

17

Ничего не волшебство в жизни: если вы обновите значение, ваш 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*/} 

} 
+1

У меня создалось впечатление, что наблюдатель немедленно уведомляет всех своих подписчиков каждый раз, когда объект наблюдает за изменениями. Поэтому в основном нам нужно постоянно сообщать всем этим подписчикам, чтобы они прислушивались к любым изменениям? –

+1

Вам нужно постоянно сообщать всем своим Наблюдаемым, что что-то меняется. Затем все абоненты будут уведомлены. – dwursteisen

+0

Мне было интересно, что если я хотел бы асинхронно возвращать что-то из 'map' внутри' method'. Я имею в виду 'return String.valueOf (value);' - асинхронный вызов. –

7

@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 в вашем классе для создания более продвинутых моделей поведения.

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