如何为变量创建更改侦听器?

时间:2013-03-15 13:35:55

标签: java variables event-handling

假设我使用语句int someVariable;定义了一些变量。代码运行时,变量的值会发生变化。

如何跟踪此变量的变化?我怎样才能实现一些行为类似onSomeVariableChangedListener的Listener?

我还需要知道一个页面中的其他方法何时被执行,所以我可以在另一个类中设置一个Listener。

5 个答案:

答案 0 :(得分:35)

Java为您提供了一种简单的Observer模式实现,但是您需要在管理侦听器通知的方法中设置您的观察变量。如果你不能扩展Observable,你可以使用合成(即,在你的类中有一个Observable实例来管理通知),或者你可以看一下java.util.Observable来了解如何滚动自己的版本

Flux.java

import java.util.Observable;

public class Flux extends Observable {
  private int someVariable = 0;

  public void setSomeVariable(int someVariable) {
    synchronized (this) {
      this.someVariable = someVariable;
    }
    setChanged();
    notifyObservers();
  }

  public synchronized int getSomeVariable() {
    return someVariable;
  }
}

Heraclitus.java

import java.util.Observable;
import java.util.Observer;

public class Heraclitus implements Observer {
  public void observe(Observable o) {
    o.addObserver(this);
  }

  @Override
  public void update(Observable o, Object arg) {
    int someVariable = ((Flux) o).getSomeVariable();
    System.out.println("All is flux!  Some variable is now " + someVariable);
  }
}

答案 1 :(得分:28)

这是隐藏 setter / getter 对后面变量的众多原因之一。然后在setter中,您可以通知您的侦听器已经以适当的方式修改了此变量。正如其他人所评论的那样,没有内置的方法可以完全按照你的意愿去做,你需要自己实现它。

另外Benjamin提出了一个有趣的模式,称为Decorator模式,如果无法修改相关代码,这可能对您有用。 You can look up more info at wikipedia

这个想法是围绕一个对象构建一个兼容的包装器。让我们说你的对象是MyClass类型。

class MyClass{
   publc void doFunc(){...}
}

class MyLoggedClass extends MyClass{
    MyClass myObject;

    publc void doFunc(){
        //Log doFunc Call

       myObject.doFunc();

    }
}

而不是

MyClass object = new MyClass();

你会用

MyClass object = new MyLoggedClass(new MyClass());

现在你的其余代码将按照正常使用对象,除了每个函数调用都将被记录或通知等。

正如您将在维基百科中看到的,这通常是通过所讨论的类继承的接口来完成的,但在您的情况下这可能是不可能的。

答案 2 :(得分:3)

我相信你必须实施Observer Pattern

答案 3 :(得分:1)

您可以使用视图模型。首先创建一个扩展视图模型的类。我叫我NameViewModel。

import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;

public class NameViewModel extends ViewModel {
private MutableLiveData<String> currentName;

public MutableLiveData<String> getCurrentName(){
        if(currentName == null){
            currentName = new MutableLiveData<>();
        }
        return currentrName;
    }
}

然后在活动中,变量值的更改首先定义NameViewModel类的实例:

private NameViewModel mNameViewModel;

然后在onCreate中使用此代码段

mNameViewModel = ViewModelProvider.of(this).get(NameViewModel.class)
mNameViewModel.getCurrentName().observe(this, new Observer<String>() {
    @Override
    public void onChanged(@Nullable String name) {
        //do what you want when the varriable change.
    }
});

如果要更改名称的值,可以使用以下代码段:

mNameViewModel.getCurrentName().postValue(String newName);

我使用postValue(),因为如果要使用UI线程,我想从工作线程中更新变量,则应使用setValue()。 现在,每次更改变量都会更新UI。

答案 4 :(得分:0)

如果任意变量的值发生变化或者某个方法被调用,则Java中没有内置的方法来获取通知。