我正在尝试遵循 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
当我尝试在主 (UI) 线程中使用任何类型的文件访问或 SQL 时,Android 现在对我大喊大叫。但我看到很多建议在主线程中使用文件访问和/或 SQL。例如,主要活动应该在内部加载默认偏好值onCreate()
,以防它们尚未设置:
PreferenceManager.setDefaultValues(context, resId, readAgain);
糟糕——这会导致在第一次应用程序执行时访问文件,因为onCreate()
在 UI 线程上调用。我能看到的唯一解决方法是启动一个单独的线程——它引入了一个与其他 UI 代码的竞争条件,这些代码可能会读取首选项并期望已经设置了默认值。
还要考虑诸如 DownloadManager 之类的服务。(实际上,它的 bug 太大了以至于在现实生活中毫无用处,但让我们假装它工作一秒钟。)如果您排队下载,您会收到一个事件(在主线程上),告诉您下载已完成。要实际获取有关该下载的信息(它只为您提供下载 ID),您必须查询 DownloadManager --- 这涉及一个光标,如果您打开了严格的策略,则会给您一个错误。
那么故事是什么——在主线程中访问游标可以吗?或者这是一件坏事,有一半的 Android 开发团队和 Android 书籍作者忘记了这一点?