Fragment (Фрагменты). Часть шестая

Кот из фрагментов

Удержание состояния фрагментов

В предыдущей статье мы рассмотрели, как сохранять данные при изменении конфигурации и других операциях.

Но есть другая проблема - нам нужно сохранить не просто данные, а работающий объект. К примеру, наш объект воспроизводит музыку или видео. Мы можем сохранить название песни, время проигрывания и т.д, но при повороте музыка прервётся, так как объект будет уничтожен вместе с фрагментом. Нужен другой подход.

У фрагмента есть свойство retainInstance, которое по умолчанию содержит значение false. Это означает, что при поворотах фрагмент не сохраняется, а уничтожается и создается заново вместе с активностью-хостом. Вызов setRetainInstance(true) сохраняет фрагмент, который не уничтожается вместе с активностью, а передается новой активности в неизменном виде.


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

Представление фрагмента может уничтожаться и создаваться заново без необходимости уничтожать сам фрагмент. При изменении конфигурации (повороте) FragmentManager сначала уничтожает макет фрагмента в своем списке. Макеты фрагментов всегда уничтожаются и создаются заново по тем же причинам, по которым уничтожаются и создаются заново разметки активности: в новой конфигурации могут потребоваться новые ресурсы. Затем FragmentManager проверяет свойство retainInstance каждого фрагмента. Если оно равно false (по умолчанию), FragmentManager уничтожает экземпляр фрагмента. Фрагмент и его макет будут созданы заново новым экземпляром FragmentManager новой активности.

Если значение retainInstance равно true, макет фрагмента уничтожается, но сам фрагмент остаётся. При создании новой активности новый экземпляр FragmentManager находит сохранённый фрагмент и воссоздаёт его макет.

Сохранённый фрагмент не уничтожается, а отсоединяется (detached) от «умирающей» активности. В сохранённом состоянии фрагмент всё ещё существует, но не имеет активности-хоста.

Переход в сохранённое состояние происходит только при выполнении двух условий:

  • для фрагмента был вызван метод setRetainInstance(true)
  • активность-хост уничтожается для изменения конфигурации (обычно поворот). Фрагмент находится в сохранённом состоянии очень недолго — от момента отсоединения от старой активности до повторного присоединения к новой, немедленно создаваемой активности.

Сохранённые фрагменты продолжают существовать только при уничтожении активности при изменения конфигурации. Если активность уничтожается из-за того, что системе потребовалось освободить память, то все сохранённые фрагменты также будут уничтожены.