Развлечения до интернета, Керби, Англия, 1973 год.

Развлечения до интернета, Керби, Англия, 1973 год.

Продолжение.

Лучшие практики для lifecycle-aware components

  • Держите контроллеры пользовательского интерфейса (действия и фрагменты) максимально возможно тонкими. Они не должны пытаться иметь свои собственные данные; вместо этого используйте ViewModel для этого и наблюдайте за LiveData, чтобы отразить изменения в представлениях.
  • Попытайтесь написать пользовательские интерфейсы, управляемые данными, где ответственность вашего контроллера пользовательского интерфейса заключается в обновлении представлений при изменении данных или уведомлении действий пользователя обратно в ViewModel.
  • Поместите логику данных (data logic) в класс ViewModel. ViewModel должен служить соединителем между вашим контроллером пользовательского интерфейса (действия и фрагменты) и остальной частью вашего приложения. Однако будьте осторожны, это не обязанность ViewModel извлекать данные (например, из сети). Вместо этого ViewModel должен вызвать соответствующий компонент для выполнения этой работы, а затем предоставить результат обратно контроллеру пользовательского интерфейса.
  • Data Binding  Используйте привязку данных для поддержания чистого интерфейса между вашими представлениями и контроллером пользовательского интерфейса. Это позволяет сделать ваши объявления более декларативными и свести к минимуму код обновления, который необходимо записать в ваших действиях и фрагментах. Если вы предпочитаете делать это на Java, используйте библиотеку, например Butter Knife, чтобы избежать шаблонного кода (boilerplate code) и иметь лучшую абстракцию.
  • Если ваш пользовательский интерфейс является сложным, подумайте о создании класса Presenter для обработки изменений пользовательского интерфейса. Это может быть трудоемкой задачей, но это может сделать ваши компоненты пользовательского интерфейса более легкими для тестирования.
  • Никогда не ссылайтесь на контекст View или Activity в ViewModel. Если ViewModel переживает активность (в случае изменений конфигурации), ваша активность будет протекать и не будет правильно собрана сборщиком мусора.

Использование lifecycle-aware components

Компоненты, совместимые с жизненным циклом, могут значительно облегчить вам управление жизненными циклами в самых разных случаях. Несколько примеров:

  • Переключение между coarse и fine обновлениями местоположения. Используйте компоненты, совместимые с жизненным циклом, чтобы обеспечить fine обновления местоположения, когда ваше приложение местоположения видно, и переключиться на coarse обновления, когда приложение находится в фоновом режиме. LiveData — компонент, зависящий от жизненного цикла, позволяет вашему приложению автоматически обновлять пользовательский интерфейс при изменении местоположения использования.
  • Остановка и запуск буферизации видео. Используйте компоненты, совместимые с жизненным циклом, для запуска буферизации видео как можно скорее, но отложите воспроизведение до тех пор, пока приложение не будет полностью запущено. Вы также можете использовать компоненты, зависящие от жизненного цикла, для прекращения буферизации, когда ваше приложение будет уничтожено.
  • Запуск и остановка сетевого подключения. Используйте компоненты, совместимые с жизненным циклом, для обеспечения прямого обновления (потоковой передачи) сетевых данных, когда приложение находится на переднем плане, а также автоматически приостанавливается, когда приложение переходит в фоновый режим.
  • Приостановка и возобновление анимационных drawables. Используйте компоненты, совместимые с жизненным циклом, для обработки приостановки анимационных чертежей, когда приложение находится в фоновом режиме и возобновляет чертежи после того, как приложение находится на переднем плане.

 

Читать ещё :   Руководство по архитектуре приложений. Часть 2

Обработка stop событий

Когда Lifecycle принадлежит AppCompatActivity или Fragment, состояние Lifecycle изменяется на CREATED, и событие ON_STOP посылается при вызове функции onSaveInstanceState() AppCompatActivity или Fragment.

Когда состояние Fragment или AppCompatActivity сохраняется через onSaveInstanceState (), его пользовательский интерфейс считается неизменным до тех пор, пока не вызывается ON_START. Попытка изменить пользовательский интерфейс после сохранения состояния может вызвать несоответствия в состоянии навигации вашего приложения, поэтому FragmentManager генерирует исключение, если приложение запускает FragmentTransaction после сохранения состояния. Подробнее см. commit().

LiveData предотвращает появление этого крайнего случая, воздерживаясь от вызова своего наблюдателя, если связанный с ним Lifecycle не был, по крайней мере,  STARTED. За кулисами он вызывает isAtLeast(), прежде чем принимать вызов своего наблюдателя.

К сожалению, метод onStop() AppCompatActivity вызывается после onSaveInstanceState(), который оставляет зазор, когда изменения состояния пользовательского интерфейса не разрешены, но жизненный цикл еще не перемещен в состояние CREATED.

Чтобы предотвратить эту проблему, класс Lifecycle в версии beta2 и ниже отметит состояние CREATED без отправки события, чтобы любой код, который проверяет текущее состояние, получает реальное значение, даже если событие не отправлено до тех пор, пока onStop () не будет вызван.

К сожалению, это решение имеет две основные проблемы:

  • На уровне API 23 и ниже система Android фактически сохраняет состояние активности, даже если она частично закрыта другой деятельностью. Другими словами, система Android вызывает onSaveInstanceState (), но не обязательно вызывает onStop (). Это создает потенциально длинный интервал, когда наблюдатель все еще считает, что жизненный цикл активен, даже несмотря на то, что его состояние пользовательского интерфейса не может быть изменено.
  • Любой класс, который хочет подвергнуть аналогичное поведение классу LiveData, должен реализовать обходной путь, предоставляемый версией Lifecycle бета 2 и ниже.

Примечание. Чтобы упростить этот поток и обеспечить лучшую совместимость со старыми версиями, начиная с версии 1.0.0-rc1, объекты Lifecycle отмечены как CREATED и ON_STOP отправляется, когда вызывается onSaveInstanceState(), не дожидаясь вызова onStop() метод. Это вряд ли повлияет на ваш код, но это то, о чем вам нужно знать, поскольку оно не соответствует порядку вызова в классе Activity в API-интерфейсе 26 и ниже.

 

Читать ещё :   Работа с Lifecycles с помощью Lifecycle-Aware компонент. Часть 2

Читать еще