假设我使用语句int someVariable;
定义了一些变量。当代码运行时,变量的值会发生变化。
如何跟踪该变量的变化?我怎么能实现一些监听器的行为像onSomeVariableChangedListener?
我还需要知道一个页面中的其他方法何时被执行,以便我可以在另一个类中设置侦听器
Java为这类事情提供了一个简单的Observer模式实现,但是您需要在管理侦听器通知的方法中设置观察到的变量。如果你不能扩展Observable,你可以使用composition(即,在你的类中有一个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);
}
}
这是将变量隐藏在setter/getter对后面的众多原因之一。然后,在setter中,您可以通知侦听器该变量已以适当的方式被修改。正如其他人所评论的那样,没有内置的方法可以精确地完成您想要的,您需要自己实现它。
另外,Benjamin提出了一个有趣的模式,称为Decorator模式,如果有问题的代码无法修改,它可能对您有用。你可以在维基百科上查找更多信息这个想法是在对象周围构建一个兼容的包装器。假设你的对象的类型是MyClass。
class MyClass{
public void doFunc(){...}
}
class MyLoggedClass extends MyClass{
MyClass myObject;
public void doFunc(){
//Log doFunc Call
myObject.doFunc();
}
}
不是MyClass object = new MyClass();
使用
MyClass object = new MyLoggedClass(new MyClass());
现在剩下的代码将像往常一样使用object,除了每个函数调用将被记录或通知等。
正如您将在Wikipedia中看到的那样,这通常是通过相关类继承的接口完成的,但在您的情况下可能不可能。
您可以使用视图模型。首先创建一个扩展视图模型的类。我把我的命名为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.
}
});
如果您想更改name的值,可以使用以下代码片段:
mNameViewModel.getCurrentName().postValue(String newName);
我使用postValue(),因为我想从工作线程更新变量,如果你在UI线程上,你应该使用setValue()。现在每次变量被改变时,它都会更新UI
我相信你将不得不实现观察者模式。
如果任意变量的值发生变化或者某个方法被调用,Java中没有内置的方法来获得通知。