所以我想为所有应用程序活动创建一个数据库实例。 我找到了以下代码:
public class MyApplication extends Application {
private static SQLiteDatabase mDB = null;
@Override
public void onCreate() {
super.onCreate();
DataBaseOpenHelper m_OpenHelper = new DataBaseOpenHelper( this );
mDB = m_OpenHelper.getWritableDatabase();
}
public static SQLiteDatabase getDB() {
return mDB;
}
}
我不知道何时可以关闭SQLiteDatabase实例。
答案 0 :(得分:13)
当我刚开始使用Android时,这对我来说是一个问题,因为网上没有很多教程描述如何正确地允许在整个应用程序中访问您的数据库(不要问我原因)。以下是一些展示三种可能方法的示例代码。
如果您知道您的应用程序不会非常复杂(例如,如果您知道您最终只有一个Application
的子类),那么您可以创建Application
的子类并且具有你的主要活动扩展它。这可确保数据库的一个实例在整个应用程序的整个生命周期中运行。
public class MainApplication extends Application {
/**
* see NotePad tutorial for an example implementation of DataDbAdapter
*/
private static DataDbAdapter mDbHelper;
/**
* create the database helper when the application is launched
*/
@Override
public void onCreate() {
mDbHelper = new DataDbAdapter(this);
mDbHelper.open();
}
/**
* close the database helper when the application terminates.
*/
@Override
public void onTerminate() {
mDbHelper.close();
mDbHelper = null;
}
public static DataDbAdapter getDatabaseHelper() {
return mDbHelper;
}
}
这不是完整的实现,但它应该让您对如何正确设计DatabaseHelper
类有所了解。静态工厂方法确保任何时候只存在一个DatabaseHelper实例。
/**
* create custom DatabaseHelper class that extends SQLiteOpenHelper
*/
public class DatabaseHelper extends SQLiteOpenHelper {
private static DatabaseHelper mInstance = null;
private static final String DATABASE_NAME = "databaseName";
private static final String DATABASE_TABLE = "tableName";
private static final int DATABASE_VERSION = 1;
private Context mCxt;
public static DatabaseHelper getInstance(Context ctx) {
/**
* use the application context as suggested by CommonsWare.
* this will ensure that you dont accidentally leak an Activitys
* context (see this article for more information:
* http://developer.android.com/resources/articles/avoiding-memory-leaks.html)
*/
if (mInstance == null) {
mInstance = new DatabaseHelper(ctx.getApplicationContext());
}
return mInstance;
}
/**
* constructor should be private to prevent direct instantiation.
* make call to static factory method "getInstance()" instead.
*/
private DatabaseHelper(Context ctx) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.mCtx = ctx;
}
}
这是我建议的方法。首先,新的LoaderManager
类在很大程度上依赖于ContentProviders,所以如果你想要一个Activity或Fragment来实现LoaderManager.LoaderCallbacks<Cursor>
(我建议你利用它,它是神奇的!),你需要为您的应用程序实现ContentProvider
。此外,您不必担心使用ContentProviders创建Singleton数据库帮助程序。只需从Activity中调用getContentResolver()
,系统就会为您处理所有事情(换句话说,不需要设计Singleton模式来防止创建多个实例)。
希望有所帮助!
答案 1 :(得分:2)
你真的不需要关闭它。当您的流程终止时,它将自动关闭。您可以只使您的数据库帮助程序对象成为单例以便于访问,而不是使用Application对象。 BTW,getWritableDatabase()
和getReadableDatabase()
并没有那么不同。唯一的区别是getReadableDatabase()
可能如果你没有空间可以工作,而另一个会抛出异常。
答案 2 :(得分:0)
我不认为这是推荐的,如果有任何东西你可以拥有DataBaseOpenHelper的全局实例,并在你真正需要数据库的地方调用getWritableDatabase()。显然,只在需要时获取可写实例,否则使用getReadableDatabase()。
我不确定这背后的原因,但我的猜测是这是一个昂贵的对象来获取和/或保持,所以你不想在应用程序加载并保持时创建它全局实例。也许其他人可以澄清这一点。我希望Android文档可以更好地解释这一点,因为我也有这样的冲动。