2012-12-21 17 views
0

我有SQLite數據庫(PlaceDbProvider)的工作類。這是單獨的。問題是我有三個使用PlaceDbProvider的活動。什麼時候最好調用PlaceDbProvider的銷燬方法?我很困惑,因爲每個活動都有自己的onDestroy方法。關閉應用程序中的SQLite數據庫與幾個活動

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); 
    } 
} 

}

回答

0

1)實例化PlaceDbProvider與應用程序上下文(context.getApplicationContext())

2)創建應用程序中的類應用程序類

3),在onTerminate( )方法,調用(PlaceDbProvider)onDestroy()方法

(請參閱我在此鏈接創建應用程序類的其他答案:https://stackoverflow.com/a/13994622/1789730

+1

但onTerminate()方法用於模擬過程環境。它永遠不會在生產Android設備上被調用....? –

1

Singleton模式不推薦用於Android,因爲持有Singleton對象的活動或服務可能會根據Android的Apps生命週期銷燬。我建議你擴展應用程序的應用程序對象,並將靜態引用部署到數據庫。

另一方面,嘗試使用ContentProvider進行數據庫處理。起初它對於簡單的任務可能聽起來太多了,但當使用CursorAdapters和Loaders顯示SQLite數據時,ContentProvider-ContentResolver組合提供了很大的幫助。如果使用此方法,則不需要數據庫初始化或關閉。

希望它有幫助。

0

這是更好地實現方法打開和關閉這樣的:

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

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

注:將對DBAdapter這是你與數據庫工人階級。在你想從數據庫中讀取/插入/更新數據的時刻之前,你應該立即打開你的數據庫,並立即關閉它,在onDestroy()中是不必要的。

0

我沒有看到使用單例模式的特定問題,只要您正確實施它。確實,使用單例的Activity或Service可能會被銷燬,但如果您可以重新創建單例,這並不重要。只要記得保持線程安全,就可以將數據庫引用作爲單例。如果引用被破壞,只需重新打開數據庫即可。

要關閉它,不管你在哪裏,你可以從你想要的任何地方調用Database.close(),然後在調用SQLiteDatabase.close()之前檢查單例以查看數據庫是否關閉。即使您的應用程序仍處於打開狀態,您可能會決定每次結束時都要關閉數據庫。

我同意你等待打開數據庫,直到你準備好讀/寫。作爲一個說明,如果在調用SQLiteDatabase.close()之前調用SQLiteDatabase.isOpen(),它應該不會影響您嘗試關閉它的位置。

相關問題