我有片段,我在每个片段中缓存数据。我通过从服务器下载doInBackground方法将数据缓存在AsyncTask中,并将其保存在onPostExecute中保存到我的数据库中。所以我总是在onPostExecution中打开数据库连接。如果我滚动“快速”扔掉片段,我认为AsyncTasks通过预览实例,行中将有android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
,我打开连接(获取dbHelper.getWritableDatabase()
)
我认为有两种方法可以解决这个问题:
onPostExecution方法必须等到预览AsyncTask(onPostExecution)完成
有一种方法可以为AsyncTask的所有实例使用相同的数据库连接,而不会互相锁定它们
这是对的吗?有人有点想法,怎么做?
答案 0 :(得分:5)
我建议您使用Loader而不是AsyncTask在后台加载数据。否则,您必须管理游标,与UI线程正确同步,并确保在后台线程上发生所有查询。此外,非常不鼓励使用现已弃用的startManagingCursor和managedQuery方法;他们放慢了你的应用程序的速度,并且可以让它戛然而止。
Android 3.0引入了 Loader和LoaderManager 类来帮助简化流程。这两个类都可以在Android支持库中使用,它支持所有Android平台返回到Android 1.6。
加载程序确保所有游标操作完成异步,从而消除了阻止UI线程的可能性。此外,当由LoaderManager管理时,Loaders在活动实例上保留其现有的游标数据(例如,当由于屏幕旋转而重新启动时),从而将游标保存在不必要的,可能昂贵的重新查询中。作为一个额外的好处,Loaders足够智能,可以监控底层数据源的更新,并在数据更改时自动重新查询。
请查看此博客,了解有关加载程序的更多信息 http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html
或访问Android开发人员的官方文档: http://developer.android.com/guide/components/loaders.html
答案 1 :(得分:1)
我认为您要查找的所有信息都可以在这篇文章中找到:
What are the best practices for SQLite on Android?
至于使用onPostExecution在db上保存数据,因为SQLiteDatabase类是线程安全的,所以如果你在doInBackground方法中执行它,你的应用程序会更快(并且仍然安全)。
请记住,如果保存数据是由多个SQL查询组成的,那么通过使用事务很容易确保它们以原子方式执行(不受其他线程的干扰):
SQLiteDatabase's beginTransaction() at the Android developers website
无论如何都应该使用btw(在单个事务中插入1000行会大大加快速度)
希望这有帮助