Android loader, loadermanager

Мітки: LoaderManager. Loader. LoaderManager.LoaderCallbacks. AsyncTaskLoader. CursorLoader

У старих версіях Android при роботі з курсором використовувалися методи, які тепер вважаються застарілими.

  • startManagingCursor (Cursor)
  • managedQuery (Uri, String, String, String, String)

Перший метод працював в життєвому циклі активності. Курсор автоматично деактивовано або закривався, коли активність зупинялася або закривалася. При рестарт активності, курсор також активізувався, створюючи повторний запит до даних.

Другий метод здійснював сам запит. Проблема з методами полягала в тому, що вони працювали в одному потоці з інтерфейсом програми та виконували зайві запити при зміні стану активності, гальмуючи весь додаток, якщо база даних була занадто велика.

Наприклад, завантажимо дані в список старим способом, використовуючи контент-провайдер. Результат обробляється адаптером SimpleCursorAdapter і виводиться на екран.

Від цього коду слід відмовитися з описаних вище причин, щоб не мати проблем з продуктивністю.

Починаючи з Android 3.0, з'явився інший механізм роботи з курсором - завантажувач Loader і менеджер LoaderManager. які також доступні в бібліотеці сумісності для старих пристроїв.

Тепер всі операції з курсором відбуваються в асинхронному режимі. А дані кешуються і при необхідності інформація оновлюється, якщо дані змінилися.

LoaderManager

LoaderManager дозволяє грамотно управляти завантажувачами, пов'язаними з активністю або фрагментом. Кожна активність і кожен фрагмент має один екземпляр менеджера LoaderManager. який працює з завантажувачами через методи initLoader (). restartLoader (). destroyLoader (). Активність через даного менеджера може попередити про своє знищення, щоб LoaderManager в свою чергу закрив завантажувачі для економії ресурсів.

Сам LoaderManager не знає, як дані завантажуються в додаток. Він просто дає вказівки завантажувачу почати, зупинити, оновити завантаження даних і інші команди.

LoaderManager працює з об'єктами Loader. де D є контейнером для даних при завантаженні. При цьому дані не обов'язково повинні бути курсором. Це можуть бути і List. JSONArray і т.д. В одній активності може бути кілька загрузчиков, які є об'єктами.

Клас Loader є загальним. Також доступні спеціалізовані завантажувачі AsyncTaskLoader і CursorLoader.

Робота з LoaderManager відбувається через три методу зворотного виклику інтерфейсу LoaderManager.LoaderCallbacks .

інтерфейс LoaderManager.LoaderCallbacks

інтерфейс LoaderManager.LoaderCallbacks визначає порядок взаємодії з завантажувачем через методи:

onCreateLoader ()

Метод onCreateLoader () повертає новий завантажувач. LoaderManager викликає метод при створенні Loader.

При спробі доступу до завантажувача (наприклад, за допомогою методу initLoader ()), він перевіряє, чи існує завантажувач, вказаний за допомогою ідентифікатора. Якщо він не існує, він викликає метод onCreateLoader (). Саме тут і створюється новий завантажувач.

onLoadFinished ()

Метод onLoadFinished викликається автоматично, коли Loader завершує завантаження даних. Завантажувач стежить за надходять даними, а менеджер отримує повідомлення про завершення завантаження і передає результат даного методу.

Цей метод гарантовано викликається до вивільнення останніх даних, які були надані цьому завантажувачу. До цього моменту необхідно повністю перестати використовувати старі дані (оскільки вони скоро будуть замінені). Однак цього не слід робити самостійно, оскільки даними володіє завантажувач і він подбає про це. Завантажувач вивільнить дані, як тільки дізнається, що додаток їх більше не використовує. Наприклад, якщо даними є курсор з CursorLoader. не слід викликати close () самостійно. Якщо курсор розміщується в CursorAdapter. слід використовувати метод swapCursor () з тим, щоб старий Cursor не закрили.

onLoadReset ()

Метод onLoadReset () перезавантажує дані в засобі завантаження.

Цей метод викликається, коли стан створеного раніше завантажувача скидається, в результаті чого його дані губляться. Цей зворотний виклик дозволяє дізнатися, коли дані ось-ось будуть вивільнені, з тим щоб можна було видалити свою посилання на них.

Порядок роботи менеджера загрузчиков під час створення активності.

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]
SearchView.onQueryChangeText (Пошук по тексту, див. Приклади нижче)
RestartLoader
LoaderManager.LoaderCallbacks.onCreateLoader
LoaderManager.LoaderCallbacks.onLoadFinished

При знищенні активності:

Activity.onStop ()
Activity.onDestroy ()
LoaderManager.LoaderCallbacks.onLoaderReset () // Зверніть увагу, що цей метод викликається

Завантажувач (Loader)

Менеджер завантажувачів управляє завантажувачами. Завантажувач призначений для завантаження даних з джерела: диск, база даних, контент-провайдер, мережа або інший процес. Завантажувач виробляє вибірку даних без блокування головного потоку в окремому потоці і доставляє результати стороні, яка в них зацікавлена, стежачи за змінами даних та інформує про всі важливі зміни менеджеру через спеціальні слухачі.

Таким чином, активність або фрагмент не цікавляться, як завантажуються дані. Вони довірили цю роботу завантажувачу.

Існують три вбудованих типу загрузчиков: Loader. AsyncTaskLoader і CursorLoader. Loader - базовий клас, який сам по собі не дуже корисний. Він визначає API, який використовується LoaderManager для взаємодії з усіма завантажувачами.

AsyncTaskLoader

Для завдань асинхронної завантаження даних в окремому потоці використовується клас, що успадковує AsyncTaskLoader замість Loader. клас AsyncTaskLoader є абстрактним і працює як AsyncTask. На основі цього класу ви можете реалізувати абстрактний метод loadInBackground ().

Слухач отримує інформацію від завантажувача. Для цього менеджер реєструє слухач OnLoadCompleteListener. який прослуховує події. Коли завантаження закінчилася, то викликається метод onLoadFinished (Loader loader, D result).

Щоб завантажувач почав працювати, його треба запустити. Запущений завантажувач стежить за даними, поки його не перезапускатимуть або зупинять.

Зупинений завантажувач продовжує моніторити зміни в даних, але не повідомляє про них. При необхідності ви можете заново запустити або перезапустити зупинений завантажувач.

При перезапуску завантажувач не повинен запускати нову завантаження даних і моніторити зміни. Його завдання - звільнити зайві дані. Цей стан рідко використовується, але в деяких випадках воно потрібно.

Ваше завдання зводиться до створення власного завантажувача, реалізації методу loadInBackground () і перевизначенні методів onStartLoading (). onStopLoading (). onReset (). onCanceled (). deliverResult (D results).

Невеликий приклад для демонстрації. Приклад звідси.

Створимо кнопку і текстову мітку на екрані.

Створимо клас завантажувача, який успадковується від AsyncTaskLoader. Наш завантажувач буде повертати рядок, тому вкажемо :

Мінлива mWord буде зберігати базову рядок, на основі якої буде створюватися випадкова рядок. Цей параметр передається при створенні завантажувача в конструктор з використанням об'єкта Bundle. Константа RANDOM_STRING_LENGTH задає максимальну довжину нової випадкової рядки.

Наслідуючи від AsyncTaskLoader. ми переобумовленої кілька методів:

  • loadInBackground () - метод, в якому власне і повинна бути створена вся робота по завантаженню даних
  • onStartLoading () - спрацьовує при запуску завантажувача (але це ще не означає завантаження даних)
  • onStopLoading () - спрацьовує при зупинці завантажувача
  • deliverResult () - отримує і повертає підсумковий результат роботи завантажувача
  • forceLoad () - «примусова» завантаження нових даних

Для отримання даних в методі loadInBackground () ми викликаємо допоміжний метод generateString (). який генерує випадкову рядок.

Клас активності реалізує інтерфейс LoaderManager.LoaderCallbacks з його методами, що дозволяє нам «брати участь» у життєвому циклі завантажувача і взаємодіяти з LoaderManager.

Метод onCreateLoader () - викликається при ініціалізації завантажувач. Якщо завантажувач з таким ідентифікатором вже був створений, то метод не зголоситься. Всередині ми визначаємо, який ідентифікатор нам був переданий, щоб створити потрібний завантажувач. Якщо завантажувач тільки один, то умова можна прибрати.

Метод onLoadFinished () викликається по закінченню завантаження. У метод приходять завантажені дані, а також об'єкт завантажувача. Отриману рядок ми виводимо в текстовій мітці.

Метод onLoaderReset () викликається при «скиданні» стану завантажувача. Тут дані обнуляються, і нам потрібно видалити всі наявні посилання на них.

Клацання кнопки виконує роль тригера для запуску нового завантаження даних. Ми використовуємо метод onContentChanged (). щоб сигналізувати завантажувачу про зміну даних.

Як відбувається перший запуск завантажувача? Ми це робимо в методі onCreate (). ініціалізувавши завантажувач. При ініціалізації ми передаємо в параметрах ідентифікатор завантажувача, Bundle - об'єкт, що містить передані аргументи (ми передаємо базову рядок) і покажчик на callback-об'єкт (в нашому випадку - це сама активність).

Ну тепер запускаємо додаток і дивимося логи. При натисканні на кнопку текст оновлюється, але в логах ми вже не бачимо повторного створення завантажувача.

CursorLoader

Клас CursorLoader є спадкоємцем класу Loader і працює з курсором в асинхронному режимі. CursorLoader розширює AsyncTaskLoader для завантаження Cursor з ContentProvider через ContentResolver.

додаткове читання

Схожі статті