如何将我的SQLHelper设置为Singleton

时间:2014-01-07 14:29:51

标签: java android singleton android-sqlite

我想知道是否可以让我的SQLHelper从SQLiteOpenHelper扩展为Singleton类。

我的问题是:

要使用该类从SQLiteOpenHelper扩展的对象,我需要在实例化我的类时传递一个“this”的上下文。 事实上,我想在任何地方使用我的助手,而不必再次实例化......

如果有人作为我的解决方案,用一个例子说明,那就太好了:)

谢谢你!

这是我目前所拥有的课程,我想以Singleton的形式出现:

public class SQLHelper extends SQLiteOpenHelper {

/*
 Attributs
*/

public SQLHelper(Context context){
    super(context, DATABASE_NAME, null, 23);
}

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_TABLE_CATEGORIES = "CREATE TABLE " + TABLE_CATEGORIES + "(" + CATEGORY_NAME + " TEXT," + CATEGORY_ID + " INTEGER, " + CATEGORY_ID_PARENT + " INTEGER," + CATEGORY_URL_IMAGE + " TEXT" + ")" ;
    String CREATE_TABLE_INFOS = "CREATE TABLE " + TABLE_INFOS + "(" + INFOS_AGE + " INTEGER," + INFOS_MAIL + " TEXT," + INFOS_DISPLAY_PRICE + " TEXT," + INFOS_TOKEN + " TEXT," + INFOS_REFRESH_TOKEN + " TEXT," + INFOS_TOKEN_EXPIRATION + " TEXT, " + INFOS_REFRESH_TOKEN_EXPIRATION + " TEXT, " + INFOS_APP_VERSION + " TEXT" + ")";
    String CREATE_TABLE_ITEMS = "CREATE TABLE " + TABLE_ITEMS + "(" + ITEM_ID + " INTEGER," + ITEM_NAME + " TEXT," + ITEM_CATEGORY_ID + " INTEGER," + ITEM_PRICE + " REAL" + ")";
    String CREATE_TABLE_SHOPPING_LIST = "CREATE TABLE " + TABLE_SHOPPING_LIST + "(" + SHOPPING_LIST_ID + " INTEGER," + SHOPPING_LIST_NAME + " TEXT," + SHOPPING_LIST_DATE_CREATION + " TEXT" + ")";
    String CREATE_TABLE_SHOPPING_LIST_ITEMS = "CREATE TABLE " + TABLE_SHOPPING_LIST_ITEMS + "(" + SHOPPING_LIST_ITEMS_LIST_ID + " INTEGER," + SHOPPING_LIST_ITEMS_ID + " INTEGER," + SHOPPING_LIST_ITEMS_NB_ITEMS + " INTEGER," + SHOPPING_LIST_ITEMS_CHECKED + " INTEGER" + ")";
    db.execSQL(CREATE_TABLE_CATEGORIES);
    db.execSQL(CREATE_TABLE_INFOS);
    db.execSQL(CREATE_TABLE_ITEMS);
    db.execSQL(CREATE_TABLE_SHOPPING_LIST);
    db.execSQL(CREATE_TABLE_SHOPPING_LIST_ITEMS);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_CATEGORIES);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_INFOS);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEMS);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_SHOPPING_LIST);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_SHOPPING_LIST_ITEMS);
    onCreate(db);
}
/*
 Methods
*/
}

3 个答案:

答案 0 :(得分:0)

你可以做类似的事情,但我认为这不是一个好主意:

private static DataBaseHelper instance;

private DataBaseHelper() {
    super(App.getAppContext(), DB_NAME, null, 1);
    this.context = context;
}   

public static DataBaseHelper getInstance() {
    if (instance == null) {
        instance = new DataBaseHelper();
    }
    return instance;
}

答案 1 :(得分:0)

转到私有构造函数和getInstance方法

public class SQLHelper extends SQLiteOpenHelper {

private static SQLHelper sqlHelper = null;

private SQLHelper(Context context){
    super(context, DATABASE_NAME, null, 23);
}

public static SQLHelper getInstance(){
if(sqlHelper == null){
sqlHelper = new SQLHelper(context);
return sqlHelper;
}
return sqlHelper;
}

答案 2 :(得分:0)

不 - 在一轮回合中,你回答了自己的问题。因为您需要提供参数(在本例中为context)来创建SQLiteHelper单例模式不起作用,因为每次初始化对象时它必须是不同的。单身人士只有在需要一个相同的对象来协调整个系统的功能时才会工作,而不仅仅是当你只想要一个对象的副本时。

您是否可以强制执行代码,以便只存在SQLiteHelper的一个副本?当然 - 看看下面:

private static volatile Class mClass  null;

public static Class getInstance(Context context){
    if(mClass == null){
        synchronized(Class.class){
            if(mClass == null){
                mClass = new Class(context);
            }
        }
    }
    return mClass;
}

你一开始认为这是一个好主意。它看起来像是创建单例的合法方式(虽然根据 Effective Java ,有更好的方法来执行此操作,如使用enum类型)。实际上,您只能获得一个Class初始化的副本。问题是context在每种情况下都会出错,除了第一种情况。你不必成为单身人士的专家就能意识到这只是一个坏主意。