我正在创建一个应用程序,允许Activities从a TabActivity(最多~25)启动许多不同的应用程序.大多数活动都需要来自sqlite数据库的数据,因此在onCreate运行时,AsyncTask会创建一个SQLiteOpenHelper对象(它将打开一个可读/可写的数据库),运行查询,检索数据,然后关闭所有内容.
我只是在考验插科打诨,看看我能打破一些东西,所以我说每Activity到TabActivity's TabHost.然后我开始尽快将每个标签混合.
我注意到很快我就开始在LogCat中看到了:Caused by: android.database.sqlite.SQLiteException: database is locked: BEGIN EXCLUSIVE;应用程序继续死亡.
通常情况下,只有大约4-6个标签(我可以只限制用户)TabHost.我无法通过少量标签来破坏任何东西,但我仍然担心我可能会以糟糕的方式访问数据库.
如何防止我的SQLiteDatabase对象导致锁定?
如果我创建一个ContentProvider遗嘱,消除数据库锁定的可能性?
您是否有任何关于我可以为从中访问数据所做的更改的建议SQLiteDatabase?
我最终采用了使用Application该类并存储1 的方法,SQLiteOpenHelper并尽力使其保持同步.这似乎工作得很好 - 我把我所有的25个活动都放进TabHost去并且没有任何错误.
我在我的((SQLiteDbApplication)getApplication()).setDbHelper(new DBHelper(this, Constants.DB_NAME, null, Constants.DB_VERSION_CODE));每个onCreate()活动中都在调用方法(如下所示)
对此方法或使用此类所做的更改的任何进一步建议Application?
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()
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您担心所有数据库连接,请尝试将自己限制为一个 SqliteOpenHelper,并确保在其周围包裹一个同步层。
您可以扩展应用程序类,然后调用getApplication并将获得的对象强制转换到应用程序中。现在您可以在此应用程序类中存储 SqliteOpenHelper 并构建您自己的数据库连接线程安全访问方法。
如果您在所有 onCreate 方法中使用 AsyncTask,并且在使用大量选项卡时遇到问题,则这些问题也可能发生在较慢的设备、较快的用户或随着使用时间的推移而变大的数据库上。
根据您应用程序的用例,您可以采用保存方式并经历线程和锁定的所有努力和痛苦,或者您可以只发布带有许多从未产生错误的选项卡的应用程序,并确保捕获错误数据库异常并向自己发送通知(例如通过谷歌分析)以测试线程问题是否确实在应用程序的实际使用中发生。