Как создать прослушиватель изменений для переменной?



Предположим, что у меня есть некоторая переменная, определенная с помощью оператора int someVariable;. Во время выполнения кода значение переменной изменяется.



Как я могу отслеживать изменения в этой переменной? Как я могу реализовать некоторый слушатель, который ведет себя как onSomeVariableChangedListener?



Мне также нужно знать, когда был выполнен какой-либо другой метод на одной странице, чтобы я мог установить прослушиватель в другом классе.

617   6  

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

    Ничего не найдено.