37
почему с ними стоит дружить? Loaders

Loaders (and why we should use them)

Embed Size (px)

DESCRIPTION

In this presentation I'm talking about powerful tool for asynchronous loading which is provided by Android framework - loaders. Why guys from Android team added this tool and how we can customise it? We'll try to find answers for these questions.

Citation preview

Page 1: Loaders (and why we should use them)

почему с ними стоит дружить?

Loaders

Page 2: Loaders (and why we should use them)

Проблемахотим плавный графический интерфейс без

тормозов

Page 3: Loaders (and why we should use them)

Решениевыносим все время-затратные процессы в

фон

Page 4: Loaders (and why we should use them)

Простейший случай

Page 5: Loaders (and why we should use them)

Инструменты для решениявстроенные в Java классы для роботы с

многопоточностью (Thread, Runnable, etc)

Page 6: Loaders (and why we should use them)

Недостатки● никаких “удобств” для организации

межпроцессного взаимодействия ○ много кода - легко запутаться и допустить ошибку

● не адаптированны для Android’а○ проблемы с производительностью (если не

использовать пул потоков)○ ничего не знают про жизненный цикл

компонентов

Page 7: Loaders (and why we should use them)

Частное решение - AsyncTask● Значительно упрощает межпроцессное

взаимодействие● Использует пул (производительность++)

Page 8: Loaders (and why we should use them)

Активности не вечныочень не вечны...

Page 9: Loaders (and why we should use them)

Проблемафоновые процессы должны “переживать” пересоздание активности и доставлять

результат в новую активность

Page 10: Loaders (and why we should use them)
Page 11: Loaders (and why we should use them)

Решениеиспользовать компоненты отвязанные от

контекста активности

Page 12: Loaders (and why we should use them)

Инструменты для решения● сервис (Robospice)● RxJava + фрагменты● лоадеры● веселые комбинации из предыдущих трех

Page 13: Loaders (and why we should use them)

Справедливости ради, нужно отметить, что асинктаски все еще пользуются популярностью

Page 14: Loaders (and why we should use them)

Обычно, случается совсем не сразу после сокрытия активности + сетевые запросы не настолько длинные

Page 15: Loaders (and why we should use them)
Page 16: Loaders (and why we should use them)

Сервисы+маловероятно, что система убъет приложение+много хорошо развитых библиотек-трудности взаимодействия с сервисом-библиотеки Гуглом не поддерживаются, судьба их туманна

Page 17: Loaders (and why we should use them)

RxJava+ бОльшая ориентированность на событийную модель-+другая парадигма программирования-без Retrolambda очень много шаблонного кода

Page 18: Loaders (and why we should use them)

Кто такой этот ваш лоадер?Это кто-то умеющий:● загрузить данные● хранить их в себе● отслеживать изменения в данных и доставлять

новые данные● реагировать на события жизненного цикла

Page 19: Loaders (and why we should use them)

Состояния Loader’а● started - лоадер загружает/хранит данные и следит

за обновлениями● stopped - лоадер следит за обновлениями, но не

сообщает о них● reset - лоадер не содержит в себе данных и не

следит за изменениями

Page 20: Loaders (and why we should use them)
Page 21: Loaders (and why we should use them)

LoaderManager● привязывается к активности/фрагменту и

переживает configuration change

● хранит ссылки на лоадеры

● обеспечивает жизненный цикл лоадеров

Page 22: Loaders (and why we should use them)

Методы LoaderManager‘а○ initLoader() - создает и запускает лоадер. Если

лоадер содержит данные - возвращает их немедленно

○ restartLoader() - создает или пересоздает лоадер,

при этом данные загружаются заново

○ destroyLoader() - уничтожает лоадер

Page 23: Loaders (and why we should use them)

LoaderCallbacksТочка коммуникации View и LoaderManager

public class SampleActivity extends Activity implements LoaderManager.LoaderCallbacks<D> {

public Loader<D> onCreateLoader(int id, Bundle args) { // фабричный метод для лоадера }

public void onLoadFinished(Loader<D> loader, D data) { // обработка результатов }

public void onLoaderReset(Loader<D> loader) { // освобождение ресурсов }}

Page 24: Loaders (and why we should use them)
Page 25: Loaders (and why we should use them)

До API level 11 у активности были такие методы:

● public void startManagingCursor(Cursor)

● public void stopManagingCursor(Cursor)

● public Cursor managedQuery(Uri, String, String, String, String)

Почему все началось с курсоров?они и до сих пор есть, но deprecated

Page 26: Loaders (and why we should use them)

Но что-то было не так...+активность сама обслуживает курсор-курсор пересоздавался при пересоздании активности-все в UI потоке

Page 27: Loaders (and why we should use them)

getLoaderManager().initLoader(LOADER_ID, null, new LoaderManager.LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { return new CursorLoader(getActivity(), "content://com.foo.bar/dog", null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { if (cursor != null && cursor.moveToFirst()) someView.setText(cursor.getString(0)); } @Override public void onLoaderReset(Loader<Cursor> cursorLoader) { // если бы тут был курсор адаптер, мы бы свапнули курсор }});

CursorLoader все порешал

Page 28: Loaders (and why we should use them)

Реализация собственного Loader’а● рекомендуется использовать AsyncTaskLoader

● нужно будет переопределить○ loadInBackground()

○ onStartLoading()

○ onStopLoading()

○ onReset()

○ onCanceled()

○ deliverResult(D results)

Page 29: Loaders (and why we should use them)
Page 30: Loaders (and why we should use them)

● loadInBackground()

○ Фоновая операция. Именно в ней данные загружаются.

● onStartLoading()

○ проверить нет ли у нас загруженных данных и если есть,

то вернуть их немедленно

○ если данных нет, то форсировать их загрузку

○ запустить механизм, который будет отслеживать

изменения в данных

● onStopLoading()

○ перестать уведомлять о новых данных, но быть готовым к

старту

Page 31: Loaders (and why we should use them)

● onReset()

○ остановить загрузку

○ прекратить отслеживать изменения данных

● onCanceled()

○ попытаться остановить текущую загрузку

○ почистить загруженные данные

● deliverResult(D results)

○ если лоадер в reset состоянии - освободить ресурсы

○ иначе доставить новые данные и освободить ресурсы

устаревших данных

Page 32: Loaders (and why we should use them)
Page 33: Loaders (and why we should use them)

Сейчас я полезу в идею, показать вам немного кода для кастомного лоадера.

Наверняка что-то повлится, так что заранее прошу прощения за косячки ;)

Page 34: Loaders (and why we should use them)

Loader’ы+безболезненно переживают пересоздание+хорошо документированны+”официальный” инструмент-приложение могут убить-жизненный цикл не самый простой

Page 35: Loaders (and why we should use them)

Мораль● не стоит пренебрегать лоадерами

● для простого сетевого взаимодействия лоадеры

вполне могут подойти

● можно использовать лоадеры как фасад к

другому инструменту асинхронной загрузки

Page 36: Loaders (and why we should use them)

● Серия статей про Loaders (by Alex Lockwood)● Android networking without pain (презентация)● Modern techniques for implementing REST clients

on Android 4.0 and below● CWAC-LoaderEx and Failed Abstractions● Android tutorial to learn through small projects

(оно на китайском)● Пример на GitHub

Интересности найденные в процессе подготовки презенташки

это все ссылочки - можно кликать

Page 37: Loaders (and why we should use them)

Спасибо за внимание!

Мои контакты:Миша Пустовит

Stanfyhttps://google.com/+ПустовитМихаил