Я просмотрел множество примеров/руководств по использованию SQLite в Android. Допустим, у вас есть приложение, которое использует SQLite, ContentProvider
, CursorLoader
, обычай CursorAdapter
. Теперь все основные примеры этого, которые я нашел, полагаются на CursorLoader
для извлечения данных в CursorAdapter
, который по характеру CursorLoader
происходит в безопасном потоке Async-UI. Тем не менее, эти же примеры делают сообщения о вставке/удалении/обновлении через ContentResolver
на основной нити (например, от onClick
, onResume
,). (Example) Они не переносят эти вызовы в AsyncTask
или запускают отдельный поток или используют AsyncQueryHandler
. Почему это так, как может так много хорошо написанных блогов/примеров сделать такую очевидную ошибку? Или просто однострочные вставки/удаления/обновления одной строки так быстро, что они достаточно безопасны для запуска из потока Main/UI? Каков правильный способ совершать эти быстрые звонки?Android - SQLite ContentResolver вставка/удаление/обновление в потоке пользовательского интерфейса?
Android - SQLite ContentResolver вставка/удаление/обновление в потоке пользовательского интерфейса?
ответ
Я также путался с образцами, делающими звонки по основной теме. Я думаю, что образцы просто упростили демонстрации, избегая дополнительных потоков и обратных вызовов, поскольку один вызов insert/update/delete может быстро вернуться.
Помимо шаблона Loader для запроса, андроид предоставил вспомогательный класс AsyncQueryHandler, поскольку API-уровень 1 для операций async CRUD с полным обратным вызовом CRUD поддерживается. AsyncQueryHandler работает внутри с HandlerThread для операций async и возвращает результаты в основной поток.
Таким образом, я уверен, что запросы ContentProvider должны выполняться в рабочих потоках, отличных от пользовательского интерфейса, и эти образцы не могут быть лучшими практиками в соответствии с официальным дизайном.
=== редактировать
Найдена аннотацией из официальных рамочных документов см this или this, Line 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}.
=== редактировать 2 Link к фактическому андроиду Dev руководству, содержащему выше цитаты
Правильно, я также упомянул AsyncQueryHandler о моем вопросе ... это все еще не очень убедительно, что ВСЕ учебники и примеры, которые я пришел через это, просто потому, что он проще и даже не упоминает, что это не то, как вы должны это делать. Для правильного ответа я хотел бы получить что-то официальное от Google (член команды, doc, учебник) или что-то в этом роде (возможно, ссылка на респектабельный проект GitHub, который делает это так или иначе), что делает эти светлые звонки на Главная тема, или использует что-то вроде AsyncQueryHandler ... –
Иначе все остальное просто наше мнение по этому поводу ... :) –
@LeoK Получил официальный документ, который упоминал об этом. См. Мои правки. –
Этот вопрос был на мой взгляд с давних времен. Я думаю, это зависит от сложности файла, который мы пытаемся вставить, обновить или удалить. Если наше приложение собирается вставлять или обновлять большие файлы, всегда было бы правильно делать это асинхронно, и если файлы не будут такими большими, запуск этого файла в потоке пользовательского интерфейса может быть выполнен.
Однако всегда рекомендуется продолжать операции с базой данных в отдельном потоке.
Спасибо за ответ. Это не совсем объясняет, почему Учебники, которые объясняют лучшие практики и в других аспектах, делают вещи правильно/безопасно в случае вставки/удаления/обновления, никогда не беспокоятся об отдельных потоках. Очевидно, что я не прочитал все хорошие учебные пособия, поэтому можно было бы приветствовать хорошие примеры встречных примеров. (Особенно из Google или других авторитетных источников) –
Я думаю, вы ответили на свой вопрос. Я верю, что CursorLoader расширяет AsyncTaskLoader. Вызовы, сделанные из потока пользовательского интерфейса, обрабатывают только вызов TO CusorLoader (который использует AsyncTask.) То, что делается, по-прежнему не выполняется в потоке пользовательского интерфейса. Выполнение вызова метода/функции, который затем запускает вещи в отдельном потоке, все еще делает работу вне потока пользовательского интерфейса.
Какая работа, по вашему мнению, происходит в потоке пользовательского интерфейса?
Пожалуйста, покажите журнал отладки, если это возможно, или пример, где вы думаете, что работа выполнена в пользовательском интерфейсе. Не должно быть.
Не пытайтесь утверждать, просто хотите знать, как вы пришли к выводу о работе пользовательского интерфейса?
Вы правы, когда загрузчик курсора является асинхронным. Вот что я написал в этом вопросе. Однако вызовы вставки/удаления/обновления выполняются через ContentReslover, а не с CursorLoader. Все, что происходит через ContentReslover, выполняется в потоке пользовательского интерфейса, если вызов его выполняется в потоке пользовательского интерфейса. Это легко проверить, просто добавив Thread.sleep (5000) в начало переопределения вставки вашего ContentProvider. Если вы это сделаете, вы увидите, что ваш UI замерзает в течение 5 секунд ... –
- 1. Android: экземпляр ContentResolver потокобезопасен?
- 2. Обеспечение интерфейса обновления в потоке пользовательского интерфейса
- 3. Правильно ли делать некоторые запросы SQLite в потоке пользовательского интерфейса?
- 4. Устранение задержек в потоке пользовательского интерфейса
- 5. Загрузить изображения в фоновом потоке или потоке пользовательского интерфейса?
- 6. Курсор выборки производительности в потоке пользовательского интерфейса
- 7. Как проверить, работает ли в потоке пользовательского интерфейса в Android?
- 8. Android: SQLite операции при использовании ContentResolver
- 9. Android BroadCast Receiver работает в потоке пользовательского интерфейса
- 10. этот код нужно запускать в потоке пользовательского интерфейса Android?
- 11. Ошибка Android StrictMode для длинного запроса в потоке пользовательского интерфейса
- 12. Создание секундомера, который обновляется в потоке пользовательского интерфейса Android
- 13. Как выполнить некоторый код в асинхронном потоке пользовательского интерфейса Android?
- 14. Android ждет в потоке пользовательского интерфейса без его замораживания
- 15. Android: есть метод View.onClick(), вызванный в основном потоке пользовательского интерфейса?
- 16. Android: метод AsyncTask onPreExecute() НЕ выполняется в потоке пользовательского интерфейса
- 17. Android app app - методы блокировки в потоке пользовательского интерфейса
- 18. Что такого особенного в потоке пользовательского интерфейса?
- 19. таймаут для метода в потоке пользовательского интерфейса
- 20. Выполнение метода в потоке пользовательского интерфейса
- 21. Выполнение длинной задачи в потоке пользовательского интерфейса
- 22. Альтернатива операциям BitmapImage в потоке пользовательского интерфейса?
- 23. Продолжение задачи в потоке пользовательского интерфейса
- 24. Что работает в потоке пользовательского интерфейса?
- 25. AsyncTask не обновляется в потоке пользовательского интерфейса
- 26. Обработка компонентов пользовательского интерфейса в другом потоке
- 27. Код запуска в потоке пользовательского интерфейса
- 28. Каков приоритет потока в потоке пользовательского интерфейса?
- 29. Создание пользовательского интерфейса в фоновом потоке WPF?
- 30. Поднять событие в потоке пользовательского интерфейса
ваше последнее предложение, вероятно, правильно: операция запроса наверняка намного сложнее, чем отдельная вставка/обновление/удаление. – pskink