在 Android 應用中讀取 SQLite 資料庫時,拋出 java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery 異常,導致 Activity 啟動失敗。錯誤堆疊顯示問題發生在 Cursor.moveToNext() 呼叫處。
查看程式碼發現,在 while (c.moveToNext()) 迴圈內部呼叫了 c.close()。這導致游標在第一次迭代後就被關閉,當迴圈嘗試執行下一次 moveToNext() 時,因操作已關閉的游標而拋出異常。
游標關閉操作應放在迴圈外部,確保遍歷完成後再釋放資源。此外,資料庫連線和 Helper 也建議在 Activity 銷毀時(如 onDestroy())統一關閉,而非在讀取資料後立即關閉。
// 正確範例
Cursor c = mDataBase.rawQuery("select * from finance", null);
listData = new ArrayList<HashMap<String, Object>>();
while (c.moveToNext()) {
HashMap<String, Object> map = new HashMap<>();
// ... 資料提取邏輯 ...
listData.add(map);
}
c.close(); // 移至迴圈外部
// mDataBase.close(); // 建議在 onDestroy 中關閉
// sqLiteOpenHelper.close();
try-finally 或 try-with-resources (API 19+) 確保游標一定會被關閉。AsyncTask、Loader 或 Room 資料庫框架。SQLiteDatabase, SQLiteOpenHelper)生命週期應與元件(Activity/Service)一致。