在Android应用程序中对SQLite数据库执行查询时,最佳做法是什么?
从AsyncTask的doInBackground运行插入,删除和选择查询是否安全?或者我应该使用UI线程?我认为数据库查询可能"很重",不应该使用UI线程,因为它可以锁定应用程序 - 导致应用程序无响应(ANR).
如果我有几个AsyncTasks,他们应该共享一个连接还是应该分别打开一个连接?
这些方案是否有最佳实践?
注意:请不要将此问题标记为重复.我已经经历了几个类似的问题,但找不到满意的答案.
我一直在研究使用Sqlite数据库的应用程序.我们遵循单例模式,确保我们只能在整个应用程序中创建一个辅助类实例.
public class CustomSqliteHelper extends SQLiteOpenHelper {
public static CustomSqliteHelper getInstance(Context context) {
if (instance == null) {
synchronized (CustomSqliteHelper.class) {
if (instance == null) {
instance = new CustomSqliteHelper(context);
}
}
}
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
但有时应用程序崩溃了SQLiteDatabaseLockedException.我理解当多个线程/进程尝试一次写入数据库时会出现此异常.即使一个线程/进程在写操作仍在进行时尝试读取数据库,也会抛出此异常.
所以我一直在阅读很多关于这个以及防止这种情况发生的可能方法.很多帖子建议使用ContentProvider而不是直接扩展SqliteOpenHelper类和对数据库对象执行操作.在阅读其中一篇帖子时,这篇文章提到在使用Content Provider时,您不需要手动处理多线程环境.
虽然ContentProvider缺乏线程安全性,但通常您会发现在防止潜在的竞争条件方面您无需采取进一步行动.规范示例是您的ContentProvider由SQLiteDatabase支持的时间; 当两个线程同时尝试写入数据库时,SQLiteDatabase将自行锁定,确保一个等待直到另一个完成.每个线程都将获得对数据源的互斥访问,从而确保满足线程安全性.
以上引用似乎令人困惑,因为首先它提到ContentProvider不支持线程安全.但他总结说,应用程序开发人员不需要做任何事情来实现并发.
另外,如果我选择使用SqliteOpenHelper,那么防止这些崩溃的最佳方法是什么?我一直在考虑为每个db操作使用锁.
public class CustomSqliteHelper extends SQLiteOpenHelper {
private String lock = "lock";
public void insert(){
synchronized(lock){
// Do the insert operation here.
}
}
public void update(){
synchronized(lock){
// Do …Run Code Online (Sandbox Code Playgroud)