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

Android AsyncTask 中 SimpleCursorAdapter 空指標異常:Cursor 生命週期管理

     編輯:程式設計綜合問答

錯誤現象

doInBackground 回傳 Cursor 為 null,或在 onPostExecute 使用時已關閉,導致 NullPointerException。

常見原因

  1. dbHelper.fetchMainActivity() 內部提前呼叫 cursor.close()。
  2. 查詢無結果回傳 null 而非空 Cursor。
  3. 在背景執行緒關閉資料庫連線,導致 Cursor 失效。

修正程式碼

private class LoadNewsLists extends AsyncTask<Void, Void, Cursor> {
    @Override
    protected Cursor doInBackground(Void... params) {
        // 確保資料庫開啟,且不在這裡關閉 cursor
        return dbHelper.fetchMainActivity(); // 應回傳有效 Cursor 或空 Cursor
    }

    @Override
    protected void onPostExecute(Cursor cursor) {
        if (cursor == null) {
            Log.w("LoadNews", "Cursor is null");
            return;
        }
        try {
            String[] columns = { DatabaseUtil.rtitle, DatabaseUtil.rtypeof };
            int[] to = { R.id.idTitle, R.id.idType };
            SimpleCursorAdapter adapter = new SimpleCursorAdapter(
                MainActivity.this, R.layout.listhome, cursor, columns, to, 0);
            ListView listView = findViewById(R.id.list);
            listView.setAdapter(adapter);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 注意:若 Adapter 仍在使用 Cursor,不可在這裡 close
            // 由 Activity 生命週期管理(onDestroy 關閉)或使用 LoaderManager
        }
    }
}

現代替代方案(建議)

  • LoaderManager + CursorLoader(API 28 棄用,但支援庫仍可用):自動管理 Cursor 生命週期、配置變更重載。
  • Room + LiveData + PagingSource:編譯期 SQL 檢查、觀察者模式自動更新 UI、分頁載入。
  • Flow + Room:Kotlin 協程原生串流,取代 Loader。

關鍵原則

  1. Cursor 由建立者負責關閉,但若交給 Adapter 使用,關閉時機交給 UI 元件(如 CursorAdapter 會在 changeCursor 時關閉舊 Cursor)。
  2. 不要在背景執行緒關閉資料庫或 Cursor。
  3. 使用 try-with-resources 管理 SQLiteDatabase 連線。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved