我已阅读了几个“答案”,但找不到明确的答案。
我有一个使用AsyncTask执行数据库操作的应用程序,因此它可以在池中的任何一个线程中执行。我还有一个后台线程来执行数据同步(长时间运行)
我应该使用哪种模式?
PAttern 1:为每个操作打开和关闭,例如:
db = SQLiteOpenHelper.getWriteableDatabase()
// Do some operations such as insert / select ...
db.close();
模式2:在应用启动时打开一次,在所有线程之间共享,在应用终止时关闭,例如:
Application:
public void onCreate(){ .. open database and cache the instance ... }
模式3:实现某种形式的引用计数,以检测何时释放对缓存实例的所有引用。 (我以为Android最初已经实现了这个,但我错了)
我见过SQLiteOpenHelper.getWriteableDatabase()
的代码,如果没有关闭它会返回相同的实例。因此对于模式1,2个线程可以获得相同的实例,并且当另一个线程正在执行操作时,一个线程可能正在关闭该实例。这导致我的应用程序中的“库例程不按顺序执行”。
模式1对于多次打开和关闭来说似乎有点过分。
模式2似乎更安全,但如何检测应用何时终止?似乎没有可靠的方法。当应用程序终止时数据库未关闭会发生什么?
答案 0 :(得分:-1)
经过大量的研究和测试,我得出的结论是,关闭本地SQlite数据库并不是必需的。我使用单身SQliteOpenHelper
如下:
public class MyApplication extends Application{
private static MyApplication instance;
public MyApplication(){
instance = this;
}
public static Context getContext(){
return instance;
}
}
public class LocalDBHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "MyDB";
private static final String LOG_TAG = "LocalDBHelper";
private static LocalDBHelper instance = null;
/*private constructor to avoid direct instantiation by other classes*/
private LocalDBHelper(){
super(MyApplication.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
}
/*synchronized method to ensure only 1 instance of LocalDBHelper exists*/
public static synchronized LocalDBHelper getInstance(){
if(instance == null){
instance = new LocalDBHelper();
}
return instance;
}
...
...
}
我按LocalDBHelper.getInstance().getWritableDatabase()
获取数据库。
这里的关键点是,这可确保线程安全,并避免为每次操作不断打开和关闭数据库。在应用程序生命周期内的任何时间点,只存在一个数据库实例。它不会产生任何错误/警告。