Gar*_*son 6 android cursor ui-thread
我正在尝试遵循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
Run Code Online (Sandbox Code Playgroud)
当我尝试在主(UI)线程中使用任何类型的文件访问或SQL时,Android现在对我大喊大叫.但我看到很多建议在主线程中使用文件访问和/或SQL.例如,主活动应该在内部加载默认首选项值onCreate(),以防它们尚未设置:
PreferenceManager.setDefaultValues(context, resId, readAgain);
Run Code Online (Sandbox Code Playgroud)
糟糕 - 导致第一次应用程序执行时的文件访问,因为onCreate()在UI线程上调用.我能看到的唯一方法是启动一个单独的线程---它引入了一个竞争条件和其他可能读取偏好的UI代码,并期望已经设置了默认值.
还要考虑DownloadManager等服务.(实际上,它是如此错误,以至于它在现实生活中无用,但让我们假装它可以工作一秒钟.)如果你排队下载,你会得到一个事件(在主线程上)告诉你下载已经完成.要实际获取有关该下载的信息(它只提供下载ID),您必须查询涉及游标的DownloadManager ---如果您启用了严格的策略,则会出错.
那么故事是什么 - 在主线程中访问游标是否可以?或者这是一件坏事,Android开发团队和Android书籍作者中有一半忘记了这一点?
我能看到的唯一方法是启动一个单独的线程---它引入了一个竞争条件和其他可能读取偏好的UI代码,并期望已经设置了默认值.
然后使用a AsyncTask,将setDefaultValues()调用doInBackground()和"可能读取首选项的其他UI代码"放入其中onPostExecute().
要实际获取有关该下载的信息(它只提供下载ID),您必须查询涉及游标的DownloadManager ---如果您启用了严格的策略,则会出错.
所以DownloadManager在后台线程中查询.
那么故事是什么 - 在主线程中访问游标是否可以?
这取决于你对"罚款"的定义.
在Android 1.x和大多数2.x设备上,使用的文件系统是YAFFS2,它基本上序列化了所有进程的所有磁盘访问.实际效果是,虽然您的代码可能在单独的情况下表现得足够高,但由于后台正在进行其他事情(例如,下载新电子邮件),因此在生产中有时会显得迟缓.
虽然这在Android 3.x及更高版本中没有问题(它们切换到ext4),但毫无疑问,闪存I/O仍然相对较慢 - 它的速度可能会慢得多.
StrictMode旨在指出可能出现缓慢的地方.由您决定哪些是良性的,哪些不是.在一个理想的世界里,你要把它们全部清理干净; 在一个理想的世界里,我会有头发.
或者这是一件坏事,Android开发团队和Android书籍作者中有一半忘记了这一点?
这总是一件"坏事".
我不能代表"一半的Android开发团队".我认为,在早期,他们希望开发人员应用他们现有的开发专业知识来检测缓慢的行为 - 这与任何其他平台的性能问题没有显着差异.随着时间的推移,Loader除了系统级更改(例如,YAFFS2-> ext4)之外,他们还提供了更多模式来引导开发人员走上积极的道路(例如,框架),以减少问题.在某种程度上,他们试图解决Android引入与性能相关的明显挑战的地方,例如单线程UI.
同样,我不能代表所有Android书籍作者.我当然没有关注早期版本的书籍中的性能问题,因为我专注于Android的功能和功能.随着时间的推移,我在这些领域增加了更多建议.我还提供了与这些主题相关的开源代码.2012年,我将对我的书籍进行大规模修改,并创建更多的开源项目,以继续解决这些问题.我怀疑,鉴于你的语气,我(以及可能是其他人)在这方面完全失败了,你当然欢迎你的意见.