RxJava (or Rx.NET) equivalent of ReactiveCocoa's RACObserve

Given an arbitrary field on a Java object, I want to create an Observable that will watch that field and push a new result to an Observer every time the value of the field changes. ReactiveCocoa has a macro called RACObserve, which appears to do exactly this.

I want to know how to implement similar functionality using RxJava.

For example, say I had the following simple class:

public class Foo {
    enum State {
        Idle,
        Ready,
        Error
    }

    private State currentState = State.Idle;

    //methods that can change currentState
}

I want to create an Observable<State> that will push the new state to an Observer every time something changes the value of currentState .

In ReactiveCocoa, it looks like I would write something sort of like the following (please excuse my pseudo Objective-C):

[RACObserve(self, currentState) subscribeNext:^(NSString *newState) {
    NSLog(@"%@", newState);
}];

How would I achieve similar functionality in RxJava? I'm thinking that I may need to wrap all changes to currentState in a setter, but it's not clear to me where I should then call Observable.create and how to feed the changes of currentState to an Observer.


ReactiveCocoa is actually more similar to ReactiveUI (http://www.reactiveui.net) than just plain Rx. And in ReactiveUI, you can use this.WhenAnyValue(x => x.PropName) to do exactly what you want.


I stumbled across this same problem recently, I ended up using PropertyChangeListener, which will emit an object when a property is changed, see the following:

Update Listener:

public class GameUpdateListener {

public static Observable<Object> changed(Game game) {
    final BehaviorSubject<Object> subject = BehaviorSubject.create((Object)game);

    game.addPropertyChangeListener(new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
          subject.onNext( (Object)propertyChangeEvent.getNewValue());
        }
    });
    return subject;
  }
}

Some custom object:

public class Game {
 private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
...
  public setSomeField(String field){
       this.field = field;
       pcs.firePropertyChange("field", this.field, field);

}

public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
    pcs.addPropertyChangeListener(propertyChangeListener);
}

...

}

Observe:

Game game = new Game();
GameUpdateListener listener = new GameUpdateListener();

final Observable<Object> gameObserver = listener.changed(game);

    gameObserver.subscribe(new Action1<Object>() {
        @Override
        public void call(Object o) {
            Log.e(TAG, "Object Changed");
        }
    });


game.setSomeField("New value");

This will work fine as long as you don't need to instantiate your object again. Perhaps a solution to this is to create a local setter method and emit a change there.


Since your question title contains "or Rx.NET", here is my suggestion (I dunno bout RxJava, you may find something similar).

You probably will have to leverage some sort of mechanism in the setter. The standard way in .NET is by using the INotifyPropertyChanged interface. Then by firing the events, you can create an IObservable<T> from this stream by using Observable.FromEvent<TEvent, TArgs>()

You can find a really good example of what you want to do (.NET) here.

(credits to Rob Foncesa-Ensor)

链接地址: http://www.djcxy.com/p/77054.html

上一篇: HTTP获取请求的格式

下一篇: 相当于ReactiveCocoa的RACObserve的RxJava(或Rx.NET)