Android - SQLite ContentResolver вставка/удаление/обновление в потоке пользовательского интерфейса?

Я просмотрел множество примеров/руководств по использованию SQLite в Android. Скажем, у вас есть приложение, которое использует SQLite, ContentProvider, CursorLoader, пользовательский CursorAdapter. Теперь все основные примеры этого, которые я нашел, полагаются на CursorLoader для извлечения данных в CursorAdapter, которые по характеру CursorLoader выполняются в потоке Async-UI потоком. Тем не менее, эти же примеры делают сообщения о вставке/удалении/обновлении через ContentResolver в основном потоке (например, от onClick, onResume, onPause). (Пример) Они не переносят эти вызовы в AsyncTask или запускают отдельный поток или используют AsyncQueryHandler. Почему это так, как может так много хорошо написанных блогов/примеров сделать такую ​​очевидную ошибку? Или просто однострочные вставки/удаления/обновления одной строки так быстро, что они достаточно безопасны для запуска из потока Main/UI? Каким образом можно выполнять эти быстрые вызовы?

Ответ 1

Я также запутался в том, что образцы, вызывающие вызовы в основном потоке. Я думаю, что образцы просто упростили демонстрации, избегая дополнительных потоков и обратных вызовов, поскольку один вызов insert/update/delete может быстро вернуться.

Помимо шаблона Loader для запроса, андроид действительно предоставлял вспомогательный класс AsyncQueryHandler, поскольку API-уровень 1 для операций async CRUD с полными обратными вызовами CRUD. AsyncQueryHandler работает внутри с HandlerThread для операций async и возвращает результаты в основной поток.

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

=== edit

Нашел аннотацию из официальных документов документации, см. this или this, строка 255:

In practice, this should be done in an asynchronous thread instead of
on the main thread. For more discussion, see Loaders. If you are not
just reading data but modifying it, see {@link android.content.AsyncQueryHandler}.

=== edit 2 Ссылка в фактическое руководство разработчика Android, содержащее приведенную выше цитату

Ответ 2

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

Однако всегда рекомендуется продолжать операции с базой данных в отдельном потоке.

Ответ 3

Я думаю, вы ответили на свой вопрос. Я верю, что CursorLoader расширяет AsyncTaskLoader. Вызовы, сделанные из потока пользовательского интерфейса, обрабатывают только вызов TO CusorLoader (который использует AsyncTask.) То, что делается, по-прежнему не выполняется в потоке пользовательского интерфейса. Выполнение вызова метода/функции, который затем запускает вещи в отдельном потоке, все еще делает работу в стороне от потока пользовательского интерфейса.

Какая работа, по вашему мнению, происходит в потоке пользовательского интерфейса?

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

Не пытайтесь спорить, просто хотите знать, как вы пришли к выводу о работе пользовательского интерфейса?