Что такое WeakReference и для чего он используется в Java
Что проверяют
Понимаете ли вы, как сборщик мусора видит ссылки, и применяете ли слабые ссылки по назначению. В Android вопрос почти всегда про утечки: экран уничтожен, а кто-то продолжает держать ссылку на него, и память не освобождается.
Как отвечать
В Java четыре степени достижимости: сильная, мягкая (SoftReference), слабая (WeakReference) и фантомная. Обычная ссылка не даёт объекту собраться. Слабая позволяет обратиться к объекту, но не удерживает его: как только сильных ссылок не осталось, сборщик вправе освободить объект, а get() начнёт возвращать null.
WeakReference<Activity> ref = new WeakReference<>(activity);
Activity a = ref.get(); // одна проверка, дальше работаем с локальной ссылкой
if (a != null && !a.isFinishing()) { /* обновляем UI */ }Где уместно: обратные вызовы и обработчики, живущие дольше экрана; статический вложенный класс, которому нужен контекст; кеш на WeakHashMap, где ключ должен исчезать вместе с объектом; связка с ReferenceQueue, когда нужно узнать о сборке и подчистить служебные структуры. Полезно добавить, что для кеша картинок в Android берут LruCache с явным бюджетом памяти, а не слабые и мягкие ссылки: так поведение предсказуемо.
Где спотыкаются
Говорят, что объект соберётся, даже если на него ссылаются другие части программы. Наоборот: пока жива хотя бы одна сильная ссылка, слабая ничего не меняет. Она не освобождает память, она лишь не мешает её освободить.
Пишут проверку вида if (ref.get() != null) ref.get().update(). Между двумя вызовами объект может быть собран, и второй get() вернёт null. Результат кладут в локальную переменную и проверяют именно её.
Лечат слабой ссылкой чужую утечку. Течёт не экран, а долгоживущий владелец: незакрытая подписка, статическое поле, невыключенная задача. Правильный фикс это отписка в нужной точке жизненного цикла и хранение переживающих поворот данных в ViewModel, а слабая ссылка остаётся подпоркой там, где владельца изменить нельзя.