Как перейти с управляемого запроса на LoaderManager/CursorLoader?

Я разрабатываю приложение для Android, ориентированное на уровень API 8 (2.2, Froyo). Я использую ContentProvider, и это достаточно просто, и я использую SimpleCursorAdapter для заполнения списка, но я заметил в документации для SimpleCursorAdapter, что конструктор без флагов устарел со следующим примечанием:

This constructor is deprecated. This option is discouraged, as it results in Cursor queries being performed on the application's UI thread and thus can cause poor responsiveness or even Application Not Responding errors. As an alternative, use LoaderManager with a CursorLoader.

Поскольку я ориентируюсь на уровень API 8, LoaderManager не привязан к Activity. Это делает класс FragmentActivity в пакете совместимости, но я не использую фрагменты.

Мой вопрос: как именно я должен использовать LoaderManager/CursorLoader в приложении, ориентированном на уровень API до 11? Должен ли я перейти к фрагментам или мне просто вернуться к устаревшему конструктору SimpleCursorAdapter (но использовать AsyncTask, чтобы он оставался дружественным к потоку пользовательского интерфейса, что и должен делать CursorLoader)?


person mkuech    schedule 17.01.2012    source источник
comment
Ознакомьтесь с этим сообщением в блоге: Понимание LoaderManager (часть 2)   -  person Adrian Monk    schedule 02.08.2012
comment
Здравствуйте, где задокументировано, что LoaderManager привязан к фрагментам? Это просто для получения данных из БД. Уровень модели всегда отделен от уровня пользовательского интерфейса в любой сложной программной парадигме.   -  person IgorGanapolsky    schedule 02.01.2014
comment
@IgorGanapolsky В документации для LoaderManager: Interface associated with an Activity or Fragment for managing one or more Loader instances associated with it. This helps an application manage longer-running operations in conjunction with the Activity or Fragment lifecycle ... и единственные типы Activity, связанные со старыми платформами, - это FragmentActivity.   -  person mkuech    schedule 20.02.2014
comment
Правильно, пользователь сказал: я вынужден перейти на фрагменты. Ответ - нет. Обычная активность отлично подойдет для этих целей.   -  person IgorGanapolsky    schedule 21.02.2014
comment
@IgorGanapolsky Верно, но только в API постфрагментов. Вам не нужно переходить на Fragments, но вы, по крайней мере, должны перейти на Activity, который поддерживает Fragments (что тривиально). Не возражаю, просто поясняю, если кто-то все еще поддерживает GB или более раннюю версию.   -  person mkuech    schedule 28.03.2014


Ответы (1)


Редактировать:

Я довольно много писал о LoaderManager в этом записи блога. Проверьте это и дайте мне знать, если это полезно! :)


Исходный пост:

Определенно, определенно, определенно идите с LoaderManager. Класс CursorLoader разгружает работу по загрузке данных в поток и сохраняет данные постоянными во время краткосрочных событий обновления активности, таких как изменение ориентации. В дополнение к выполнению исходного запроса CursorLoader регистрирует ContentObserver с запрошенным вами набором данных и вызывает forceLoad() при изменении набора данных и, таким образом, автоматически обновляется. Это чрезвычайно удобно, так как вам не нужно беспокоиться о выполнении запросов самостоятельно. Конечно, можно использовать AsyncTask, чтобы сделать ваше приложение дружественным к потокам пользовательского интерфейса, но это потребует гораздо больше кода... и реализация вашего класса, чтобы он, например, сохранял загруженные Cursor поверх Activity, не будет быть простым. Суть в том, что LoaderManager/Loader сделает это автоматически за вас, а также позаботится о правильном создании и закрытии Cursor на основе жизненного цикла Activity.

Чтобы использовать LoaderManager/CursorLoader в приложении, ориентированном на уровень API до 11, просто используйте класс FragmentActivity в пакете совместимости. FragmentActivity — это просто Activity, созданный для поддержки совместимости с Android и не требующий использования Fragment в вашем приложении. Просто используйте getSupportLoaderManager() вместо getLoaderManager() и все будет готово. Конечно, вы можете реализовать родительский элемент FragmentActivity для каждого экрана и отображать его макет в виде Fragment (используя FragmentActivity.getSupportFragmentManager() в методе Activity onCreate()). Этот дизайн может упростить переход к макетам с несколькими панелями, если вы когда-нибудь решите оптимизировать свое приложение для планшетов. Это тоже хороший опыт обучения :).

Это тоже неплохой учебник. . Попробуйте пройти через это и не стесняйтесь оставлять комментарии, если у вас есть другие вопросы.

person Alex Lockwood    schedule 17.01.2012
comment
обратите внимание, что существует опечатка в руководстве, которое я опубликовал. в остальном это здорово! :) - person Alex Lockwood; 17.01.2012
comment
Хм, я пытался это сделать, но мой взгляд был пустым. Я, должно быть, пропустил что-то еще. Но хорошо, когда есть направление! Спасибо! Однако один вопрос: в чем именно заключается вред от использования CursorLoader непосредственно внутри моей деятельности по сравнению с использованием его внутри LoaderManager? Из любопытства, смогу ли я просто пропустить использование LoaderManager и воспользоваться теми же преимуществами (помимо необходимости управлять своим собственным курсором)? - person mkuech; 18.01.2012
comment
Вреда нет, но вы теряете все преимущества использования LoaderManager. Для больших экранов становится более важным, чтобы вы запрашивали в отдельном потоке, поскольку изменения конфигурации включают воссоздание всего макета представления (и вы не хотите, чтобы что-либо блокировало эту операцию на планшете, поскольку макеты часто более сложны). В любом случае вы можете реализовать свой класс для выполнения этого в отдельном потоке, используя AsyncTask, как я упоминал ранее, но я хочу сказать, что LoaderManager делает все это за вас (и также управляет курсором), так что это очень удобно и довольно легко заставить его работать слишком. - person Alex Lockwood; 18.01.2012
comment
Что конкретно вы пытаетесь настроить, но ничего не получается? - person Alex Lockwood; 18.01.2012
comment
Спасибо, это очень познавательно! Чтобы ответить на ваш вопрос о пустом представлении, это была просто потеря здравомыслия в отношении моих тестовых данных (цифры). Теперь он работает отлично. Это определенно проще реализовать для асинхронных запросов! - person mkuech; 18.01.2012
comment
В руководстве предполагается, что вы работали с этим руководством. , что, вероятно, объясняет ваше замешательство. - person Alex Lockwood; 26.05.2012
comment
Учебник очень сбивает с толку на шаге 3, где говорится об изменениях в методе onCreate(). Он нигде не говорит о FragmentActivity. @AlexLockwood Я не скажу, что это лучший учебник. Это угрюмо нуждается в редактировании. Но +1 за ваш ответ. - person Gaurav Agarwal; 26.05.2012
comment
@AlexLockwood - Привет, отличные предложения. Я следовал вашему ответу выше и учебнику, на который вы ссылались. Однако я получаю исключение IllegalArgumentException. Я разместил свой код и вопрос здесь. Если у вас есть немного времени, чтобы посмотреть на него и увидеть что-то не так, я был бы признателен. Спасибо. - person ControlAltDelete; 04.08.2012
comment
@Alex Lockwood Является ли LoaderManager и CursorLoader лучшей практикой в ​​наши дни, скажем, для загрузки данных SQLite в RecyclerView? Предлагают ли новые методы, такие как JobIntentService() или JobScheduler, какие-либо существенные преимущества? - person AJW; 08.10.2018