我正在创建一个允许许多不同的应用程序 Activities
从 TabActivity
开始(最多约 25 个)。大多数 Activity 都需要来自 sqlite 数据库的数据,所以当 onCreate
运行,一个AsyncTask
创建一个 SQLiteOpenHelper 对象(它将打开一个可读/可写数据库),运行查询,检索数据,然后关闭所有内容。
我只是想弄乱一下看看我是否可以破坏某些东西,所以我添加了每个 Activity
到 TabActivity's
TabHost
.然后我开始尽可能快地混合每个选项卡。
我注意到我很快就开始在 LogCat 中看到:Caused by: android.database.sqlite.SQLiteException: database is locked: BEGIN EXCLUSIVE;
然后该应用程序继续死亡。
对于 TabHost
,通常只有大约 4-6 个选项卡(无论如何我可以限制用户) .我无法通过少量选项卡来破坏任何东西,但我仍然担心我访问数据库的方式可能很糟糕。
如何防止我的 SQLiteDatabase 对象导致锁定?
如果我创建一个 ContentProvider
这会消除数据库锁定的可能性吗?
对于我可以为从 SQLiteDatabase
访问数据所做的更改,您有什么建议吗? ?
我最终采用了使用 Application
的方法类和存储 1 SQLiteOpenHelper
并尽力保持同步。这似乎工作得很好——我把我所有的 25 个 Activity 都放在 TabHost
中并毫无错误地将它们混搭在一起。
我调用 ((SQLiteDbApplication)getApplication()).setDbHelper(new DBHelper(this, Constants.DB_NAME, null, Constants.DB_VERSION_CODE));
每个 onCreate()
中的方法(如下所示)在我的 Activity 中
对这种方法或我使用此 Application
所做的更改的任何进一步建议类(class)?
import android.app.Application;
import android.database.sqlite.SQLiteDatabase;
public class SQLiteDbApplication extends Application {
private DBHelper dbHelper;
private SQLiteDatabase db;
public synchronized DBHelper getDbHelper() {
db = dbHelper.getDatabase();//returns the already opened database object
while(db.isDbLockedByCurrentThread() || db.isDbLockedByOtherThreads());
return dbHelper;
}
public synchronized void closeDb() {
if(null != dbHelper)
dbHelper.close();
if(null != db)
db.close();
}
@Override
protected void finalize() throws Throwable {
if(null != dbHelper)
dbHelper.close();
if(null != db)
db.close();
super.finalize();
}
public synchronized void setDbHelper(DBHelper dbHelper) {
if(null == this.dbHelper) {
this.dbHelper = dbHelper;
this.dbHelper.setDb(this.dbHelper.getWritableDatabase());//creates and sets the database object via getWritableDatabase()
}
}
}
最佳答案
如果您担心所有的数据库连接,请尝试将自己限制在一个 SqliteOpenHelper 上,并确保在其周围包裹一个同步层。
您可以扩展 application类然后调用getApplication并将您获得的对象转换到您的应用程序中。现在你可以在这个应用程序类中存储一个 SqliteOpenHelper 并构建你自己的线程安全访问数据库连接的方法。
如果您在所有 onCreate 方法中都使用 AsyncTask,并且您遇到大量选项卡的问题,这些问题也可能发生在较慢的设备、较快的用户或随着使用时间而变大的数据库上。
根据您应用的用例,您可以选择省事的方式,经历线程和锁定的所有努力和痛苦,或者您可以只发布带有多个从未产生错误的选项卡的应用,并确保捕获数据库异常并向自己发送通知(例如通过谷歌分析)以测试线程问题是否确实发生在应用程序的实际使用中。
关于android - 在创建与 SQLite 数据库交互的方法/Activity 时,我应该多注意线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3755900/