首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android SQLite IllegalStateException:嘗試重新打開已關閉的物件解決方案

     編輯:程式設計疑難解答

問題現象

在 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+) 確保游標一定會被關閉。
  • 避免在 UI 執行緒執行耗時資料庫操作,可考慮使用 AsyncTask、Loader 或 Room 資料庫框架。
  • 資料庫連線物件(SQLiteDatabase, SQLiteOpenHelper)生命週期應與元件(Activity/Service)一致。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved