在Android应用程序中对SQLite数据库执行查询时,什么是最佳实践?

从AsyncTask的doInBackground运行INSERT、DELETE和select查询安全吗?还是应该使用UI线程?我认为数据库查询可能很"重",不应该使用UI线程,因为它可能会锁定应用程序,从而导致Application Not Responding(ANR).

如果我有几个异步任务,它们应该共享一个连接还是各自打开一个连接?

对于这些场景有什么最佳实践吗?

推荐答案

从多个线程插入、更新、删除和读取通常都可以,但Brad的answer不正确.你必须小心如何建立和使用你的关系.有些情况下,即使数据库没有损坏,更新调用也会失败.

The basic answer.

SqliteOpenHelper对象保持一个数据库连接.它似乎为您提供了读写连接,但实际上没有.调用只读,无论如何,您都会获得写数据库连接.

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

因此,一个帮助器,一个数据库连接,用Java代码序列化.一个线程,1000个线程,如果您使用它们之间共享的一个助手实例,则所有的数据库访问代码都是串行的.生活是美好的(差不多).

如果同时try 从实际的不同连接写入数据库,则其中一个将失败.它不会等到第一次写完后再写.它不会写下你的变化.更糟糕的是,如果没有在SQLiteDatabase上调用正确版本的insert/update,就不会出现异常.你只需要在日志(log)中得到一条信息,就这样.

那么,多线程?使用一个助手.时期如果您知道只有一个线程将被写入,那么您可能可以使用多个连接,并且您的读取速度会更快,但请注意.我没试过那么多.

下面是一篇更详细的博客文章和一个示例应用程序.

Gray和我实际上正在完成一个ORM工具,它基于他的Ormlite,与Android数据库实现协同工作,遵循我在博客文章中描述的安全创建/调用 struct .那应该很快就会出来的.瞧一瞧.


同时,还有一篇后续博文:

另外,按照前面提到的锁定示例中的2point0判断fork :

Android相关问答推荐

致命信号6(SIGABRT)MAUI应用程序在android net发布时崩溃.8、使用强制屏幕方向和并发GC

修改参数应该应用于哪些子元素?

泛型类型lambda函数参数作为函数参数

Jetpack Compose:带芯片的Textfield

如何在Jetpack Compose中创建这个圆形?

Color.Transparent 和 Color.Unspecified 之间的区别

如何使用react native下载android中/data/data/[应用程序包名称文件夹]/files中的文件

无法插入 LayoutNode@cc72396 子级,因为它已有父级

如何在jetpack compose中使可组合的屏幕zoom 到不同的手机(屏幕)尺寸?

参数化类RecyclerView.Adapter的原始使用

Andorid Studio编译器如何自动为变量editText生成mutableStateOf("")的方法名?

如何在这段代码android jetpack compose中实现全屏滚动

设置背景图片组成Column

如何用jetpack compose实现垂直李克特量表

Jetpack 将 Grid 与基于大小的自适应列数组合在一起

如何在 BottomBar jetpack compose 中删除选定的椭圆项目 colored颜色

Int 传递给 Intent 但Android工作室说我传递了一个字符串

Android Studio xml 预览问题无法初始化编辑器

在 Room 中创建一对多关系时,@Relation 类是什么意思?

Jetpack 使用 Canvas 组成半圆