Доступен ли SQL или общий доступ к файлам в основном потоке пользовательского интерфейса Android?

Я пытаюсь следовать лучшим практикам Android, поэтому в режиме отладки я включаю следующее:

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all thread violations StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all virtual machine violations 

Android теперь кричит на меня, когда я пытаюсь использовать любой вид доступа к файлам или SQL в основном потоке (UI). Но я вижу так много рекомендаций по использованию доступа к файлам и / или SQL в основном потоке. Например, основное действие должно загружать значения предпочтений по умолчанию внутри onCreate() если они еще не установлены:

 PreferenceManager.setDefaultValues(context, resId, readAgain); 

К сожалению, это приводит к доступу к файлу при первом выполнении приложения, потому что onCreate() вызывается в потоке пользовательского интерфейса. Единственный способ, который я вижу, – начать отдельный поток, который вводит условие гонки с другим кодом UI, который может читать настройки и ожидать, что значения по умолчанию уже будут установлены.

Подумайте также о таких сервисах, как DownloadManager. (На самом деле, это настолько багги, что в реальной жизни это бесполезно, но давайте притворимся, что это работает на секунду.) Если вы ставите в очередь загрузку, вы получаете событие (в основном потоке), сообщающее вам, что загрузка завершена. Чтобы получить информацию об этой загрузке (она дает вам только идентификатор загрузки), вы должны запросить DownloadManager — который включает в себя курсор, который дает вам ошибку, если включена строгая политика.

Итак, что же это за история? Хорошо ли получить доступ к курсорам в основном потоке? Или это плохо, и половина разработчиков Android и авторов книг Android забыли об этом?

Единственный способ, который я вижу, – начать отдельный поток, который вводит условие гонки с другим кодом UI, который может читать настройки и ожидать, что значения по умолчанию уже будут установлены.

Затем используйте AsyncTask , поместив setDefaultValues() в doInBackground() и «другой код пользовательского интерфейса, который может читать настройки» в onPostExecute() .

Чтобы получить информацию об этой загрузке (она дает вам только идентификатор загрузки), вы должны запросить DownloadManager — который включает в себя курсор, который дает вам ошибку, если включена строгая политика.

Поэтому запросите DownloadManager в фоновом потоке.

Итак, что же это за история? Хорошо ли получить доступ к курсорам в основном потоке?

Это зависит от вашего определения «штраф».

На устройствах Android 1.x и большинства 2.x используется файловая система YAFFS2, которая в основном сериализует весь доступ к диску во всех процессах. Чистый эффект заключается в том, что, хотя ваш код может казаться достаточно совершенным по отдельности, он кажется медленным время от времени в процессе производства из-за других вещей, происходящих в фоновом режиме (например, загрузка нового сообщения электронной почты).

Хотя это немного меньше проблем в Android 3.x и выше (они переключились на ext4), нет сомнений в том, что флеш-ввод-вывод все еще относительно медленный – он будет немного более предсказуемо медленным.

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

Или это плохо, и половина разработчиков Android и авторов книг Android забыли об этом?

Это всегда было «плохо».

Я не могу говорить за «половину команды разработчиков Android». Я предполагаю, что на раннем этапе они ожидали, что разработчики будут применять свой существующий опыт разработки для выявления вялого поведения – это существенно не отличается от проблем с производительностью на любой другой платформе. Со временем они предлагали больше шаблонов для управления разработчиками в положительном ключе (например, инфраструктура Loader ), в дополнение к изменениям на системном уровне (например, YAFFS2-> ext4), чтобы сделать это менее проблематичным. В частности, они пытаются найти места, где Android вводит различные проблемы, связанные с производительностью, такие как однопоточный интерфейс.

Точно так же я не могу говорить за всех авторов книг Android. Я, конечно, не сосредоточился на проблемах производительности в ранних выпусках моих книг, так как я фокусировался на функциях и функциях Android. Со временем я добавил больше советов в этих областях. Я также внесли открытый исходный код, связанный с этими темами. В 2012 году я буду делать огромные изменения в своих книгах и создавать больше проектов с открытым исходным кодом, чтобы продолжить решение этих проблем. Я подозреваю, учитывая ваш тон, что я (и, возможно, другие) – это полные неудачи в ваших глазах в этом отношении, и вы, безусловно, приветствуете свое мнение.