Лоадеры (loaders) в Android. Для чего нужны. Конспект.
Краткое описание. Создание. Использование.
Глобальная концепция: разработаны для работы с данными: загрузки (сохранения) данных (создание отдельного потока загрузки, загрузка, обработка ошибок, оповещение о состоянии загрузки). Нас интересует (в данный момент) одно частное применение лоадеров, а именно использование при пересоздании Activity (при изменении конфигурации) для сохранения состояния Activity
Лоадер – это компонент Android, который через класс LoaderManager связан с жизненным циклом Activity и Fragment. Это позволяет использовать их без опасения, что данные будут утрачены при закрытии приложения или результат вернется не в тот коллбэк. Разберем простейший пример (который хоть и простейший, но требует немало кода, это один из недостатков лоадеров). Создаем класс лоадера (для простоты он не будет грузить данные с сервера, а лишь имитировать загрузку):
В методе loadInBackground() - мы должны загрузить данные Integer - в данном примере это контейнер для данных (int), которые загружает наш лоадер.
В отличие от AsyncTask-а лоадер не нужно запускать вручную, это делается неявным образом через класс LoaderManager. У этого класса есть два метода с одинаковой сигнатурой:
- int id - идентификатор лоадера для различения их между собой;
- Bundle args - класс Bundle, с помощью которого передаем аргументы для создания лоадера;
- LoaderManager.LoaderCallbacks
callback - Callback для создания лоадера и получения от него результата работы:
- onCreateLoader(int id, Bundle args) - необходимо вернуть нужный лоадер в зависимости от id, используя параметры из Bundle. Вызывается автоматически, при создании лоадера;
- onLoadFinished(Loader
loader, D data) - в параметре D мы получим результат работы лоадера. Вызывается после того, как лоадер загрузит даннные. Для определения этого момента менеджер регистрирует слушатель OnLoadCompleteListener , который прослушивает события; - onLoaderReset(Loader
loader) - очищаем все данные, чвязанные с данным лоадером.
Создадим экземпляр LoaderCallback для нашего StubLoader’a:
И теперь запускаем лоадер:
Результат: через две секунды после запуска Activity покажется Toast. Теперь, если мы изменим конфигурацию Activity, например, перевернём устройство, то работа лоадера должна начаться заново и Toast должен показаться через 2 секунды. Но он показывается мнгновенно! В чём магия?
Лоадер запускается в методе initLoader класса LoaderManager. Лоадер создается при первом запуске Activity, но при последующих запусках он не пересоздаётся. Вместо этого LoaderManager заменяет экземпляр LoaderCallbacks на новый переданный, и если данные загрузились, они передаются в onLoadFinished.
Таким образом нам не нужно беспокоиться об обновлении данных и создании нового лоадера, но если данные необходимо перезагрузить, можно выполнить restartLoader.
Жизненный цикл лоадера
Порядок работы менеджера загрузчиков (LoaderManager) во время создания активности:
- Application.onCreate()
- Activity.onCreate()
- LoaderManager.LoaderCallbacks.onCreateLoader()
- Activity.onStart()
- Activity.onResume()
- LoaderManager.LoaderCallbacks.onLoadFinished()
При изменении конфигурации (поворот и т.п.):
- Application:config changed
- Activity.onCreate
- Activity.onStart
- [No call to the onCreateLoader, т.к. нет необходимости менять данные]
- LoaderManager.LoaderCallbacks.onLoadFinished
- [optionally if searchview has text in it]
- [есть необходимоть изменить данные]
- RestartLoader
- LoaderManager.LoaderCallbacks.onCreateLoader
- LoaderManager.LoaderCallbacks.onLoadFinished
При уничтожении активности:
- Activity.onStop()
- Activity.onDestroy()
- LoaderManager.LoaderCallbacks.onLoaderReset() //Обратите внимание, что этот метод вызывается