在Android应用程序中对SQLite数据库执行查询时,最佳做法是什么?
从AsyncTask的doInBackground运行插入,删除和选择查询是否安全?或者我应该使用UI线程?我想数据库查询可能“很重”,不应该使用UI线程,因为它可以锁定应用程序 – 导致Application Not Responding(ANR).
如果我有几个AsyncTasks,他们应该共享一个连接还是应该分别打开一个连接?
这些方案是否有最佳实践?
解决方法:
多个线程的插入,更新,删除和读取通常都可以,但Brad的answer不正确.您必须小心如何创建连接并使用它们.在某些情况下,即使您的数据库没有损坏,您的更新调用也会失败.
基本答案.
SqliteOpenHelper对象保留一个数据库连接.它似乎为您提供读写连接,但它确实没有.调用只读,无论如何都将获得写数据库连接.
所以,一个帮助器实例,一个数据库连接.即使您从多个线程使用它,一次一个连接. SqliteDatabase对象使用java锁来保持序列化访问.因此,如果100个线程有一个数据库实例,则对实际磁盘数据库的调用将被序列化.
所以,一个帮助器,一个db连接,在java代码中序列化.一个线程,1000个线程,如果您使用它们之间共享的一个帮助程序实例,则所有数据库访问代码都是串行的.生活是美好的(ish).
如果您尝试同时从实际的不同连接写入数据库,则会失败.它不会等到第一个完成然后写.它根本不会写你的改变.更糟糕的是,如果您没有在SQLiteDatabase上调用正确版本的插入/更新,则不会出现异常.您只需在LogCat中收到一条消息即可.
那么,多线程?使用一个帮手.期.如果你知道只有一个线程会写,你可以使用多个连接,你的读取会更快,但买家要小心.我没有测试那么多.
这是一篇博客文章,其中包含更多详细信息和示例应用.
> Android Sqlite Locking(更新链接6/18/2012)
> Android-Database-Locking-Collisions-Example by touchlab在GitHub上
Gray和我实际上是根据他的Ormlite包装一个ORM工具,该工具本身与Android数据库实现一起工作,并遵循我在博客文章中描述的安全创建/调用结构.那应该很快就会出来.看一看.
与此同时,还有一篇跟进博客文章:
还可以通过前面提到的锁定示例的2point0来检查fork:
> Android-Database-Locking-Collisions-Example by 2point0在GitHub上
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!