2011-03-02 50 views
4

進入此活動後,我收到此錯誤,開始一個新的活動,回來。當我第一次加載活動時不會發生。功能上一切正常......但我仍然得到這個錯誤。不關閉遊標或數據庫對象?

ERROR /光標(1059):結束寫入 光標還沒有被去激活 或關閉。數據庫= /data/data/com.roger.testapp/databases/data, 表= NULL,查詢= SELECT MAX(_id) FROM記錄

03-02 16:47:21.835: ERROR /光標(1059): android.database.sqlite.DatabaseObjectNotClosedException: 應用程序沒有關閉在這裏

打開 在的onCreate光標 或數據庫對象:

mDbHelper = new CommonDbAdapter(this); 
    mDbHelper.open(); 
    fillData(); 

fillData()在我的dbhelper中調用fetchNote,遊標用於幾件事情,如果rowId == 0,這意味着我沒有選擇一個項目來進入這個活動,我想獲得最後一行那張桌子。如果rowId =別的東西,那麼我抓住那一行。我認爲問題出在這裏,我只是不確定。

public Cursor fetchNote(long rowId, String table, String columns) throws SQLException { 
    if (rowId == 0) { 
     String query = "SELECT MAX(_id) FROM record"; 
     Cursor cursor = mDb.rawQuery(query, null); 
     rowId = 0;  
     if (cursor.moveToFirst()) 
     {    
      rowId = cursor.getInt(0);       
     } 
    } 
    Cursor mCursor = 
     mDb.query(true, table, new String[] {KEY_ROWID, 
       columns}, KEY_ROWID + "=" + rowId, null, 
       null, null, null, null); 
    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 

} 

在的onDestroy:

super.onDestroy(); 
    if (mDbHelper != null) { 
     mDbHelper.close(); 
    } 

另外,我startManagingCursor

+0

'super.onDestroy()'實際上是否被調用? – 2011-03-02 22:02:59

+0

我在日誌中看不到任何有關銷燬的信息。這只是我嘗試過的......似乎錯誤發生在那裏。 – Roger 2011-03-02 22:07:52

回答

2

請勿關閉您的數據庫onDestroy。在完成使用後立即關閉它(確保在數據庫關閉之前關閉每個遊標)。當您期望時,onDestroy可能不會被調用。

另外,在完成使用後關閉您的Cursor對象。

編輯: 由於您的活動正在管理Cursor,你可以考慮停止管理它,並在方法關閉一切,並在onResume開放的一切行動和fillData一次。如果你可以改變你的代碼,所以你不依賴於你的活動管理光標,你不需要保持開放的數據庫對象,並擔心它們。

+0

我一直在嘗試。儘管如此,我認爲我沒有位置。在private void fillData()(收集要發送到fetchNote的信息)的末尾,放入mDbHelper.close(); \t \t c.close();? – Roger 2011-03-02 22:11:54

+0

當我在活動中時,我可以單擊調用其他活動的項目,然後點擊後退按鈕。在我做了這5次之後,我發現錯誤。這是否提供了更多關於它可能的信息?如果我的活動停止管理光標,我總是會收到錯誤。 – Roger 2011-03-02 22:26:11

2

我建議不返回遊標。這是一個稀缺資源。

在n層Java EE中,最佳做法是在創建方法的範圍內關閉所有持久性資源(Connection,Statement和ResultSet)。將ResultSet映射到對象或集合中並關閉ResultSet。

我不知道是否有什麼特別的Android會使這個失效。

+0

在android中,你可以通過提供一個'Cursor'來自動填充一個'ListView'。 'ListActivity' [documentation](http://developer.android.com/reference/android/app/ListActivity.html)就是這樣做的,例如[Notepad Tutorial](http://developer.android.com /resources/tutorials/notepad/index.html)。如果你想使用它並仍然將你的數據庫代碼包裝到一個表類中(就像在記事本教程中那樣),你需要返回一個遊標。 – user634618 2011-03-06 14:03:25

0

看看在activity lifecycle - 你可以看到,當你從你的活動()導航路程,如果其他活動需要記憶的過程中被殺死,但是當你的用戶,然後返回到活動中,它會再次襲來onCreate 。這一次你打開一個新的CommonDbAdapter(但你從未關閉過最初的那個) - 因此當你最終擊中onDestroy時,你只會關閉最新的mDbHelper。

正如其他人所說的,最好的方法不是從DBHelper傳回光標,用數據創建對象,關閉光標並將對象傳回。關閉DBHelper一旦你使用它,你可以隨時創建另一個,如果你需要再次使用它。

+0

我將新的CommonDbAdapter移動到fillData()內部,並且在fillData()結束之前關閉了數據庫和光標。儘管如此,我仍然看到了錯誤。但是,當我從那個活動導航回來時,我不會收到錯誤......但是如果我離開,回來,走開,回來5次,然後我得到錯誤。所以也許它的內存不足,然後5次將我重新放回onCreate? – Roger 2011-03-02 22:38:41

+0

創建5個新的活動後,它很可能會耗盡空間 - 嘗試將'mDbHelper.close()'添加到'fillData()'的末尾,以確保已完成數據庫。畢竟你現在正在創建一個新的CommonDbAdapter時,功能啓動。此外,請看[startManagingCursor](http://developer.android.com/reference/android/app/Activity.html#startManagingCursor(android.database.Cursor)) – Scoobler 2011-03-02 22:44:22

+0

也應該在完成之後關閉光標它也在'fillData()'中。畢竟它光標被打開,這是拋出你的錯誤 - 不一定是數據庫被打開! – Scoobler 2011-03-02 22:48:29

相關問題