问题

在Android应用程式中对SQLite资料库执行查询时,最佳做法是什么?

从AsyncTask的doInBackground中运行插入,删除和选择查询是否安全?还是应该使用UI线程?我想数据库查询可以是"沉重的",不应该使用UI线程,因为它可以锁定应用程序 - 导致应用程序无响应(ANR).

如果我有几个AsyncTasks,他们应该共享一个连接,还是应该打开一个连接?

这些情况有什么最佳做法吗?



解决方法

插入,更新,删除和读取通常可以从多个主题执行,但Brad的回答不正确.您必须小心创建连接并使用它们.在某些情况下,即使您的数据库没有损坏,您的更新调用也会失败.

基本答案

SqliteOpenHelper对象持有一个数据库连接.它似乎为您提供读写连接,但它真的不是.调用只读,您将获得写数据库连接,无论如何.

所以,一个助手实例,一个db连接.即使你从多个线程使用它,一次一个连接. SqliteDatabase对象使用java锁来保持访问序列化.因此,如果100个线程有一个数据库实例,则对实际磁盘数据库的调用将被序列化.

所以,一个帮助器,一个数据库连接,它在java代码中序列化.一个线程,1000个线程,如果你使用一个在他们之间共享的助手实例,你的所有db访问代码是串行的.生活是好的(ish).

如果您尝试同时从实际不同的连接写入数据库,则会失败.它不会等到第一个完成然后写.它不会写你的更改.更糟糕的是,如果你不调用SQLiteDatabase上插入/更新的正确版本,你不会得到一个异常.你只会在LogCat中收到一条消息,这就是它.

那么,多线程?使用一个助手.期.如果你知道只有一个线程将写入,​​你可以使用多个连接,你的读取将更快,但买家要小心.我没有测试这么多.

这里是一个更详细的博客文章和一个示例应用程序.

灰色和我实际上包装一个ORM工具,基于他的Ormlite,本机与Android数据库实现工作,并遵循安全创建/调用结构我在博客文章中描述.这应该很快就会发生.看看.


在此期间,有一个后续博文:

还可以通过前面提到的锁定示例的 2point0 检查货叉:




相关问题推荐