Зачем в слушателе сооружать вот такую конструкцию из WeakReference?

239
26 мая 2017, 12:25

Сегодня в одном из примеров кода увидел вот такую конструкцию

private static final class ActionListener implements TextView.OnEditorActionListener {
    private final WeakReference<MainActivity> mainActivityWeakReference;
    public static ActionListener newInstance(MainActivity mainActivity) {
        WeakReference<MainActivity> mainActivityWeakReference = new WeakReference<>(mainActivity);
        return new ActionListener(mainActivityWeakReference);
    }
    private ActionListener(WeakReference<MainActivity> mainActivityWeakReference) {
        this.mainActivityWeakReference = mainActivityWeakReference;
    }
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        MainActivity mainActivity = mainActivityWeakReference.get();
        if (mainActivity != null) {
            if (actionId == EditorInfo.IME_ACTION_GO && mainActivity.shouldShowError()) {
                mainActivity.showError();
            } else {
                mainActivity.hideError();
            }
        }
        return true;
    }
}

Вот так применяется

mEditText.setOnEditorActionListener(ActionListener.newInstance(this));

Не пойму зачем использовать слабые ссылки чем это лучше старого доброго способа сразу передать слушатель

mBtnContinue.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(final View v)
        {
            doOnContinue();
        }
    });
Answer 1

Полагаю, что идея в следующем: в конкретном проекте возможна ситуация, при которой:

  1. MainActivity не требуется на экране, ему не требуется показывать сообщения, и соответствующий объект можно удалить
  2. Однако mEditText вполне нужен и хранит слушателя.

В этом случае, если бы слушатель хранил обычную ссылку на MainActivity, то сборщик мусора не имел бы права удалить соответствующий объект, что привело бы к "утечке" памяти: MainActivity не требуется, но зачем-то хранится. В случае со слабой ссылкой просто в момент удаления MainActivity слушатель из mEditText "отваливается".

Надо сказать, что некоторая утечка всё равно происходит - утекает объект класса ActionListener.

Answer 2

Здесь слабая ссылка на активити используется для ситуации, когда разработчик (зачем-то) решит сохранить ссылку на ActionListener в объекте, не привязанном к жизненному циклу (например в каком-нибудь синглетоне). Тогда, если будет обычная ссылка (не слабая), то будет утечка памяти. То есть ссылка на активити будет храниться в приложении, когда сама активити уже уничтожена.

В указанном коде используется слабая ссылка, что означает следующее: при обходе ссылок GC заметит, что на активити есть только слабая ссылка, значит объект можно удалять из памяти (объект активити удалится из памяти, даже если мы все еще храним где-то ссылку на ActionListener).

READ ALSO
Количество дней от нулевого года до сегодня

Количество дней от нулевого года до сегодня

Как можно узнать количество дней, которое прошло от "начала времен" (0 год, 1 месяц, 1 день) до сегодня?

180
Spring, ошибка при подключении views

Spring, ошибка при подключении views

Помогите! Вот такая ошибка:

250
Как поменять цвет у ImageView

Как поменять цвет у ImageView

ЗдравствуйтеИмеется класс унаследованный от LinearLayout, в котором среди прочих элементов имеется ImageView

203
Как организовать добавление в корзину в Android Firebase?

Как организовать добавление в корзину в Android Firebase?

У меня есть список блюд оформленный в виде карточек, при нажатии на карточке кнопки добавить должно происходить добавление раздел basket id этого...

214