在 Android 中处理 SQLite 单例实例及其上下文依赖性
Handling SQLite singleton instances and its Context dependency in Android
我目前正在开展一个 Android 项目,该项目与 SQLite 数据库进行大量通信。我也在尝试在应用程序中实现 MVP 框架。
我目前的Singleton 实例的实现与下面类似。 (取自这个post:https://github.com/codepath/android_guides/wiki/Local-Databases-with-SQLiteOpenHelper)
public class PostsDatabaseHelper extends SQLiteOpenHelper {
private static PostsDatabaseHelper sInstance;
public static synchronized PostsDatabaseHelper getInstance(Context context) {
if (sInstance == null) {
sInstance = new PostsDatabaseHelper(context.getApplicationContext());
}
return sInstance;
}
private PostsDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
使用上面的现有代码,我在多个 Presenter 类 中调用 getInstance 方法,将从 Activity/Fragment 传递过来的 Context 对象传递给每个 Presenter。 Context 对象可以跨多个 类.
传递
我考虑的不是上面的代码,而是在应用程序启动时仅实例化 databaseHelper 一次,然后所有引用将指向 getInstance 方法的变体,而没有上下文依赖性。
编辑:我的主要目的是尽可能多地删除 Presenter 类 中 Context 对象的存在,从而使代码 'cleaner'。因为对 getInstance provide/inject 的所有调用都是相同类型的上下文(应用程序的上下文而不是 Activity 特定的上下文),所以我认为没有必要将上下文对象作为参数。
public class PostsDatabaseHelper extends SQLiteOpenHelper {
private static PostsDatabaseHelper sInstance;
// called by all other classes
public static synchronized PostsDatabaseHelper getInstance() {
if (sInstance == null) {
//throw error
}
return sInstance;
}
// only called once at the start of the Application
public static void instantiateInstance(Context context){
sInstance = new PostsDatabaseHelper(context.getApplicationContext());
}
private PostsDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
我想知道的是,这种方法会有什么缺点吗?谢谢!
您正在将惰性初始化换成静态初始化。
一般来说,惰性初始化可以在应用程序的整个生命周期内分摊初始化成本。在这种情况下,它似乎不太重要,原因有二:
- 几乎可以肯定您会需要这个数据库。通过推迟初始化,您似乎不太可能完全避免这样做。
- Android 框架保证
DBHelper
构造函数可以来自 UI 线程 运行:这不是花时间的事情。花时间的事情是第一次调用 getWriteableDatabase
。 Helper 的懒惰创建几乎没有完成任何事情。
您可以考虑通过像这样在应用程序中初始化数据库来使代码更简单:
public class DBDrivenApp extends Application implements DBProvider {
// ...
private PostsDatabaseHelper db;
// ...
@Override
public void onCreate() {
super.onCreate();
db = new PostsDatabaseHelper(this);
}
@Override
public PostsDatabaseHelper getDB() { return db; }
// ...
}
...而且,更好的是,使用 IoC 框架(如 Dagger2)注入数据库实例,以便您可以在测试中对其进行模拟。
我目前正在开展一个 Android 项目,该项目与 SQLite 数据库进行大量通信。我也在尝试在应用程序中实现 MVP 框架。
我目前的Singleton 实例的实现与下面类似。 (取自这个post:https://github.com/codepath/android_guides/wiki/Local-Databases-with-SQLiteOpenHelper)
public class PostsDatabaseHelper extends SQLiteOpenHelper {
private static PostsDatabaseHelper sInstance;
public static synchronized PostsDatabaseHelper getInstance(Context context) {
if (sInstance == null) {
sInstance = new PostsDatabaseHelper(context.getApplicationContext());
}
return sInstance;
}
private PostsDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
使用上面的现有代码,我在多个 Presenter 类 中调用 getInstance 方法,将从 Activity/Fragment 传递过来的 Context 对象传递给每个 Presenter。 Context 对象可以跨多个 类.
传递我考虑的不是上面的代码,而是在应用程序启动时仅实例化 databaseHelper 一次,然后所有引用将指向 getInstance 方法的变体,而没有上下文依赖性。
编辑:我的主要目的是尽可能多地删除 Presenter 类 中 Context 对象的存在,从而使代码 'cleaner'。因为对 getInstance provide/inject 的所有调用都是相同类型的上下文(应用程序的上下文而不是 Activity 特定的上下文),所以我认为没有必要将上下文对象作为参数。
public class PostsDatabaseHelper extends SQLiteOpenHelper {
private static PostsDatabaseHelper sInstance;
// called by all other classes
public static synchronized PostsDatabaseHelper getInstance() {
if (sInstance == null) {
//throw error
}
return sInstance;
}
// only called once at the start of the Application
public static void instantiateInstance(Context context){
sInstance = new PostsDatabaseHelper(context.getApplicationContext());
}
private PostsDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
我想知道的是,这种方法会有什么缺点吗?谢谢!
您正在将惰性初始化换成静态初始化。
一般来说,惰性初始化可以在应用程序的整个生命周期内分摊初始化成本。在这种情况下,它似乎不太重要,原因有二:
- 几乎可以肯定您会需要这个数据库。通过推迟初始化,您似乎不太可能完全避免这样做。
- Android 框架保证
DBHelper
构造函数可以来自 UI 线程 运行:这不是花时间的事情。花时间的事情是第一次调用getWriteableDatabase
。 Helper 的懒惰创建几乎没有完成任何事情。
您可以考虑通过像这样在应用程序中初始化数据库来使代码更简单:
public class DBDrivenApp extends Application implements DBProvider {
// ...
private PostsDatabaseHelper db;
// ...
@Override
public void onCreate() {
super.onCreate();
db = new PostsDatabaseHelper(this);
}
@Override
public PostsDatabaseHelper getDB() { return db; }
// ...
}
...而且,更好的是,使用 IoC 框架(如 Dagger2)注入数据库实例,以便您可以在测试中对其进行模拟。