BadCash BadCash - 1 month ago 31
Android Question

Observable/Observer not working?

I tried implementing a static Observable in my Application subclass, but it's not working. No exceptions or error messages, but my update() callback doesn't get called.

MyApplication.java

public class MyApplication extends Application{
public static Observable appObserver = new Observable();

public void onCreate(){
super.onCreate();
}

}


Foo.java

MyApplication.appObserver.notifyObservers( "Hello world" );


BarFragment.java

public class BarFragment extends Fragment implements Observer{

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
MyApplication.appObserver.addObserver(this);
}


@Override
public void onDestroy() {
MyApplication.appObserver.deleteObserver(this);
super.onDestroy();
}


@Override
public void update(Observable observable, Object data) {
Log.i("BarFragment", data.toString()); // Should log, but doesn't
}

}


What's more, I tried scribbling down a simple Observable of my own, and then everything worked like a charm with just substituting
public static Observable appObserver = new Observable();
with
public static MyObservable appObserver = new MyObservable();


MyObservable.java

public class MyObservable {
protected List<Object> observers = new ArrayList<Object>();

public void addObserver(Object observer){
observers.add(observer);
}

public void notifyObservers(Object data){
for( int i=0; i<observers.size(); i++ ){
((Observer) observers.get(i)).update(null, data);
}
}
}


What am I missing?

I'm testing this on a Nexus One with Android 2.3.6 if it matters.

Answer

Seems I missed a crucial part of the Observer mechanism, apparently one has to call setChanged() before notifyObservers(). But the thing is, setChanged() is protected and thus only visible to any subclass of Observable.

So I guess it's not meant to be used in the fashion I tried to use it, but the hackish subclass below will work...

public class MyObservable extends Observable{

    @Override
    public boolean hasChanged() {
        return true; //super.hasChanged();
    }

}
Comments