Reputation: 13
Android, Java. Is there any method I can listen for changes to a global variable to trigger an event
For instance, if I create a global boolean variable called SeeMe in one Class. Then from a second class change the value of that global boolean to true.
Can the first class having listened out for this change, then execute Tryme();
Upvotes: 1
Views: 1157
Reputation: 14274
You want to use the Observer Pattern.
You would implement the Observable interface in your global object, and then the Observer interface for each class that needs to receive notifications.
In your case, the variable holding seeMe
would be in a class that's Observable
, and the setter method for seeMe
would call the notify()
when the value is changed. The method tryMe()
would be member of a class that's an Observer
, and would receive the call to update()
when the Observable
is changed.
Here's a sample Observable
:
import java.util.Observable;
public class GlobalValues extends Observable {
private static GlobalValues mInstance = null;
public static GlobalValues getInstance() {
if( mInstance == null )
mInstance = new GlobalValues();
return mInstance;
}
public enum ValueName { NONE, SEEME, OTHERVALUE };
static class ValueKey {
private ValueName mValueName;
public ValueKey( ValueName valueName ) {
mValueName = valueName;
}
public ValueName getKey() { return mValueName; }
}
private boolean mSeeMe = false;
public boolean getSeeMe() { return mSeeMe; }
public void setSeeMe( boolean value ) {
if( value != mSeeMe ) {
mSeeMe = value;
this.setChanged();
this.notifyObservers( new ValueKey( ValueName.SEEME ) );
}
}
}
And then you would use it like this:
import java.util.Observable;
import java.util.Observer;
public class SampleObserver implements Observer {
public void startObservingGlobals() {
GlobalValues.getInstance().addObserver( this );
}
public void stopObservingGlobals() {
GlobalValues.getInstance().deleteObserver( this );
}
public void doTryMe( boolean newSeeMe ) {
// do something when seeMe changes
}
@Override
public void update(Observable observable, Object object) {
if( observable instanceof GlobalValues ) {
if( object != null && object instanceof GlobalValues.ValueKey ) {
switch( ( (GlobalValues.ValueKey)object ).getKey() ) {
case NONE:
// General Notification
break;
case SEEME:
doTryMe( GlobalValues.getInstance().getSeeMe() );
break;
case OTHERVALUE:
// do something else
break;
}
}
}
}
}
Note that it also implements a global singleton pattern through getInstance()
, and a way to identify which value has changed through the enum
and wrapper class.
Upvotes: 2
Reputation: 3330
You cannot register observer on variables in java - this is just not possible. I would work on methods - just create setter and getter for your global variable. There are two possibilities:
You will have to generate proxy for each class that you need to "monitor". This proxy-monitor can have only one implementation, and you can register it on multiple classes. For example, in case of JDK proxy you would implement method invoke(Object proxy, Method m, Object[] args)
, and all methods calls on the proxied class will go trough invoke(....).
Such solution have one big advantage: classes that you are monitoring are not coupled to monitoring framework
Upvotes: 0