我只是在测试乱搞,看看我是否能破坏某些东西,所以我将每个Activity添加到TabActivity的TabHost中.然后我开始尽快将每个标签混合在一起.
我注意到很快我开始在LogCat中看到:引起:android.database.sqlite.sqliteException:数据库被锁定:BEGIN EXCLUSIVE;而应用程序继续死亡.
TabHost通常只有大约4-6个选项卡(我可以只限制用户).我没有能够用少量标签来破坏任何东西,但是我仍然担心我可能会以糟糕的方式访问数据库.
如果我创建一个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() } } }
解决方法
您可以扩展application类,然后调用getApplication并将您获得的对象强制转换为您的应用程序.现在,您可以在此应用程序类中存储sqliteOpenHelper,并为数据库连接构建自己的线程安全访问方法.
如果您在所有onCreate方法中使用AsyncTask并且遇到许多选项卡问题,那么这些问题也可能发生在速度较慢的设备,更快的用户或在使用时变大的数据库中.
根据您的应用程序的使用情况,您可以采用保存方式并完成线程和锁定的所有工作和痛苦,或者您可以使用许多从未产生错误的选项卡发布应用程序并确保捕获数据库异常并向您发送通知(例如通过谷歌分析),以测试在应用程序的实际使用中是否确实发生了线程问题.