通过几个活动在应用程序中关闭SQLite数据库

时间:2012-12-21 22:32:43

标签: android sqlite destroy

我有使用SQLite数据库(PlaceDbProvider)的课程。它是单音。问题是我有三个使用PlaceDbProvider的活动。什么时候最好为PlaceDbProvider调用destroy方法?我很困惑,因为每个活动都有自己的onDestroy方法。

public class PlaceDbProvider {
private static final String DB_NAME = "com.placesmanager";
private static final String TABLE_NAME = "places";
private static final int DB_VESION = 1;
private static final String KEY_ID = "_id";
private static final int ID_COLUMN = 0;
private static final String KEY_NAME = "name";
private static final int NAME_COLUMN = 1;

private Context context;
private Cursor cursor;
private SQLiteDatabase database;
private DbOpenHelper dbOpenHelper;

private static PlaceDbProvider mInstance = null;

private PlaceDbProvider(Context context) {
    this.context = context;
    init();
}

public static PlaceDbProvider getInstance(Context context) {
    if(mInstance == null) {
        mInstance = new PlaceDbProvider(context);
    }
    return mInstance;
}

public int getCount() {
    return cursor.getCount();
}


public Place getItem(int position) {
    if (cursor.moveToPosition(position)) {
        Place placeOnPositon = new Place();     
        placeOnPositon.setId(cursor.getLong(ID_COLUMN));
        placeOnPositon.setName(cursor.getString(NAME_COLUMN));
        return placeOnPositon;
    } else {
        throw new CursorIndexOutOfBoundsException(
                "Cant move cursor to postion");
    }
}


public long getItemId(int position) {
    if (cursor.moveToPosition(position)) {  
        return cursor.getLong(ID_COLUMN);
    } else {
        throw new CursorIndexOutOfBoundsException(
                "Cant move cursor to postion");
    }
}
public long addItem(Place place) {
    ContentValues values = new ContentValues();
    values.put(KEY_NAME, place.getName());
    long id = database.insert(TABLE_NAME, null, values);
    refresh();
    return id;
}
public boolean removeItem(Place placeToRemove) {
    boolean isDeleted = (database.delete(TABLE_NAME, KEY_NAME + "=?",
            new String[] { placeToRemove.getName() })) > 0;
    refresh();
    return isDeleted;
}

public boolean updateItem(long id, String key,String newValue) {
    ContentValues values = new ContentValues();
    values.put(key, newValue);
    boolean isUpdated = (database.update(TABLE_NAME, values, KEY_ID + "=?",
            new String[] {id+""})) > 0;
    return isUpdated;
}


public void destroy() {
    dbOpenHelper.close();
    mInstance = null;
}

private void refresh() {
    cursor = getAllEntries();
}

public Cursor getAllEntries() {

    String[] columnsToTake = { KEY_ID, KEY_NAME, KEY_LAT, KEY_LNG, KEY_TYPE, KEY_INFO, KEY_OWNER};

    return database.query(TABLE_NAME, columnsToTake,
            null, null, null, null, KEY_ID);
}

private void init() {
    dbOpenHelper = new DbOpenHelper(context, DB_NAME, null, DB_VESION);
    try {
        database = dbOpenHelper.getWritableDatabase();
    } catch (SQLException e) {
        Log.e(this.toString(), "Error while getting database");
        throw new Error("The end");
    }
    cursor = getAllEntries();
}

//class for creation, opening and db version control
private static class DbOpenHelper extends SQLiteOpenHelper {

    public DbOpenHelper(Context context, String name,
            CursorFactory factory, int version) {
        super(context, name, factory, version);
    }  

    @Override
    public void onCreate(SQLiteDatabase db) {
        final String CREATE_DB = "CREATE TABLE " + TABLE_NAME + " ("
                + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + KEY_NAME + " TEXT NOT NULL);";
        db.execSQL(CREATE_DB);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
}

}

4 个答案:

答案 0 :(得分:1)

不建议Android使用Singleton模式,因为根据Android的应用生命周期,可能会销毁持有Singleton对象的活动或服务。我建议您扩展应用程序的Application Object并将静态引用部署到数据库。

另一方面,尝试使用ContentProvider进行数据库处理。起初,对于简单的任务来说,它可能听起来太多了,但ContentProvider-ContentResolver组合在使用CursorAdapters和Loaders显示SQLite数据时提供了很大的帮助。如果使用此方法,则不需要数据库初始化或关闭。

希望它有所帮助。

答案 1 :(得分:0)

1)Instanciate PlaceDbProvider与应用程序上下文(context.getApplicationContext())

2)创建应用程序类

3)在你的应用程序类中,在onTerminate()方法中调用(PlaceDbProvider)onDestroy()方法

(请参阅此链接中的其他答案,以创建应用程序类:https://stackoverflow.com/a/13994622/1789730

答案 2 :(得分:0)

最好像这样实现打开和关闭的方法:

public DbAdapter open() throws SQLException
{
    dbHelper = new DbHelper(mCtx);
    db = dbOpenHelper.getWritableDatabase();
    return this;
}

public void close()
{
    dbHelper.close();
}

注意:DbAdapter它是您使用数据库的类。你想在数据库中读取/插入/更新数据之前打开数据库,然后立即关闭,在onDestroy()中不必要。

答案 3 :(得分:0)

我没有看到使用单例模式的特殊问题,只要您正确实现它。确实可以销毁使用单例的Activity或Service,但是如果你可以重新创建单例,这无关紧要。您可以将数据库引用作为单例,只要您记得保持其线程安全。如果引用被破坏,只需重新打开数据库即可。

要关闭它,无论您身在何处,都可以从任何地方调用Database.close(),然后在调用SQLiteDatabase.close()之前检查单例以查看数据库是否已关闭。即使您的应用仍处于打开状态,您也可以决定每次完成数据库时都要关闭数据库。

我同意您等到打开数据库,直到您准备好读/写为止。

请注意,如果在调用SQLiteDatabase.close()之前调用SQLiteDatabase.isOpen(),则尝试关闭它的位置无关紧要。