2014-09-10 60 views
0

我使用SQLite和SQLiteAssetHelper 2.0.1。我實現了一個單身DBHelper子類,如:Android單例SQLite,IllegalStateException:嘗試重新打開已關閉的對象:SQLiteDatabase

public class DBHelper extends SQLiteAssetHelper { 

    private static final String DB_NAME = "..."; 
    private static final int DB_VERSION = 1; 
    private static final String DB_STORAGE_DIR = "..."; 

    private static SQLiteDatabase db = null; 
    private static DBHelper instance; 

    // Create the db storage directory if it does not exist 
    static { 
     File dir = new File(DB_STORAGE_DIR); 
     if (!dir.exists()) { 
      if (!dir.mkdirs()) { 
       Log.e("BEEP", "Create database folder failed! BANG!"); 
      } 
     } 
    } 

    public static DBHelper getInstance(Context context){ 
     if(instance == null){ 
      instance = new DBHelper(context); 
     } 
     return instance; 
//  return new DBHelper(context); 
    } 

    private DBHelper(Context context) { 
     super(context, DB_NAME, DB_STORAGE_DIR, null, DB_VERSION); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     super.onUpgrade(db, oldVersion, newVersion); 
    } 

    public Cursor rawQuery(String query, String[] arguments){ 
     if(db == null || !db.isOpen()) { 
      db = getReadableDatabase(); 
     } 
     return db.rawQuery(query, arguments); 
    } 

    public void execute(String sql, Object[] arguments){ 
     if(db == null || db.isReadOnly()) { 
      db = getWritableDatabase(); 
     } 
     db.execSQL(sql, arguments); 
    } 

    public void close(){ 
     if(db != null && db.isOpen()){ 
      db.close(); 
     } 
    } 
} 

而且我得到了DBHelper實例的兩個基準假設readInstance和writeInstance用相同的情況下,我運行一些SQL這樣的:

writeInstance.read(...); 
for (int i = 0; i < n; i++) { 
    readInstance.read(...); 
    writeInstance.write(...); //IllegalStateException 
} 

然後我在DBHelper.execute方法中的寫入方法中獲取IllegalStateException。 我試圖分貝execute方法同步:

public void execute(String sql, Object[] arguments){ 
    if(db == null || db.isReadOnly()) { 
     db = getWritableDatabase(); 
    } 
    synchronized (db){ 
     db.execSQL(sql, arguments); 
    } 
} 

,但仍然得到錯誤。 任何意見將有幫助謝謝!

+0

你調用方法DBHelper ::實例()close()方法的任何地方? – 2014-09-10 10:28:02

回答

1

發現發生了什麼: 我沒有檢查execute方法中的isOpen狀態,即使db關閉,isReadOnly方法仍然返回false,所以在我以前的代碼中,我在執行方法。

FIX:

public void execute(String sql, Object[] arguments){ 
    if(db == null || !db.isOpen() || db.isReadOnly()) { 
     db = getWritableDatabase(); 
    } 
    db.execSQL(sql, arguments); 
} 
相關問題