Как создать прослушиватель изменений для переменной?
Предположим, что у меня есть некоторая переменная, определенная с помощью оператора int someVariable;. Во время выполнения кода значение переменной изменяется.
Как я могу отслеживать изменения в этой переменной? Как я могу реализовать некоторый слушатель, который ведет себя как onSomeVariableChangedListener?
Мне также нужно знать, когда был выполнен какой-либо другой метод на одной странице, чтобы я мог установить прослушиватель в другом классе.
6 ответов:
Это одна из многих причин скрывать переменные за парами setter/getter. Затем в сеттере вы можете уведомить слушателя, что эта переменная была изменена соответствующим образом. Как отмечали другие, нет встроенного способа сделать именно то, что вы хотите, вам нужно реализовать его самостоятельно.
В качестве альтернативы Бенджамин приводит интересный шаблон, называемый шаблоном декоратора, который может быть полезен вам, если код, о котором идет речь, не может быть изменен. вы можете посмотреть дополнительную информацию в Википедии Идея состоит в том, чтобы построить совместимую оболочку вокруг объекта. Допустим, рассматриваемый объект относится к типу 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());Теперь остальная часть кода будет использовать object как обычно, за исключением того, что каждый вызов функции будет регистрироваться или уведомляться и т. д.
Как вы увидите в Википедии, это обычно делается через интерфейс, который наследует рассматриваемый класс ОТ, но это может быть невозможно в вашем случае.
Java дает вам простую реализацию шаблона наблюдателя для такого рода вещей, но вам нужно будет установить наблюдаемую переменную в методе, который управляет уведомлениями слушателя. Если вы не можете расширить Observable, вы можете либо использовать composition (т. е. иметь экземпляр Observable в своем классе для управления уведомлениями), либо вы можете взглянуть на java.утиль.Наблюдаемый, чтобы получить представление о том, как свернуть свою собственную версию.
Поток.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; } }Гераклит.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); } }
Я полагаю, что вам придется реализовать шаблон наблюдателя.
Как написать прослушиватель изменения свойств может помочь вам Это что-то связанное
В Java нет встроенного способа получения уведомления, если изменяется значение произвольной переменной или был вызван какой-либо метод.
Можно использовать модель представления. Сначала создайте класс, расширяющий модель представления. Я назвал свой 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 (), так как я хочу обновить переменную из рабочего потока, если вы находитесь в потоке пользовательского интерфейса. следует использовать setValue (). Теперь каждый раз, когда переменная изменяется, она обновляет пользовательский интерфейс.
Comments