0

我有片段,我在每个片段中缓存数据。我通过从服务器以 doInBackground 方法下载数据并将其保存在 onPostExecute 中,从而将数据缓存在 AsyncTask 中。所以我总是在 onPostExecution 中打开数据库连接。如果我滚动“快速”抛出片段,我认为 AsyncTasks 正在通过预览实例,并且行中会有一个android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224),我打开连接(获取dbHelper.getWritableDatabase()

我认为有两种方法可以解决这个问题:

  • onPostExecution 方法必须等到预览 AsyncTask (onPostExecution) 完成

  • 有一种方法可以对 AsyncTask 的所有实例使用相同的数据库连接,而不会相互锁定它们

这个对吗?有人出主意,如何做到这一点?

4

2 回答 2

6

我建议您使用 Loader 而不是 AsyncTask 在后台加载数据。否则,您必须管理游标,与 UI 线程正确同步,并确保所有查询都发生在后台线程上。此外,极不鼓励使用现已弃用的 startManagingCursor 和 managedQuery 方法;它们会减慢您的应用程序的速度,并可能使其戛然而止。

Android 3.0 引入了Loader 和 LoaderManager类来帮助简化流程。这两个类都可在 Android 支持库中使用,该库支持所有 Android 平台,直至 Android 1.6。

加载器确保所有游标操作都是异步完成的,从而消除了阻塞 UI 线程的可能性。此外,当由 LoaderManager 管理时,Loader 会在 Activity 实例中保留其现有的光标数据(例如,当它由于屏幕旋转而重新启动时),从而使光标免于不必要的、可能代价高昂的重新查询。作为一个额外的好处,加载器足够智能,可以监控底层数据源的更新,并在数据更改时自动重新查询。

查看此博客以了解有关加载器的更多信息 http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

或者访问安卓开发者官方文档:http: //developer.android.com/guide/components/loaders.html

于 2013-05-28T15:51:22.170 回答
2

我认为您正在寻找的所有信息都可以在这篇文章中找到:

Android 上 SQLite 的最佳实践是什么?

至于您使用 onPostExecution 将数据保存在数据库中,由于 SQLiteDatabase 类是线程安全的,如果您在 doInBackground 方法中执行此操作,您的应用程序将更快(并且仍然安全)。

请记住,如果保存数据是由多个 sql 查询组成的,则很容易通过使用事务来确保它们以原子方式执行(不受其他线程的干扰):

Android 开发者网站上的 SQLiteDatabase 的 beginTransaction()

无论如何都应该使用哪个 btw (在单个事务中插入 1000 行会大大加快速度)

希望这可以帮助

于 2013-05-28T15:16:20.160 回答