android runtime_error ai_generated true

android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=10 (# cursors opened by this proc=10)

ID: android/room-cursor-window-allocation-failure

Also available as: JSON · Markdown · 中文
92%Fix Rate
88%Confidence
1Evidence
2023-06-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Room 2.5.0 active
SQLite 3.40.0 active
Android 13 (API 33) active

Root Cause

Too many open cursors without proper closure, exceeding the per-process cursor limit (typically 100) or memory limit.

generic

中文

打开游标过多且未正确关闭,超出每进程游标限制(通常100个)或内存限制。

Official Documentation

https://developer.android.com/reference/android/database/CursorWindowAllocationException

Workarounds

  1. 95% success Replace raw Cursor queries with Room's LiveData or Flow: @Query("SELECT * FROM users") fun getAllUsers(): LiveData<List<User>>. This ensures cursors are closed when lifecycle ends.
    Replace raw Cursor queries with Room's LiveData or Flow: @Query("SELECT * FROM users") fun getAllUsers(): LiveData<List<User>>. This ensures cursors are closed when lifecycle ends.
  2. 85% success If using raw Cursor, call cursor.close() in finally block and use ContentResolver.query with auto-close flag: val cursor = contentResolver.query(uri, null, null, null, null)?.use { it }
    If using raw Cursor, call cursor.close() in finally block and use ContentResolver.query with auto-close flag: val cursor = contentResolver.query(uri, null, null, null, null)?.use { it }

中文步骤

  1. Replace raw Cursor queries with Room's LiveData or Flow: @Query("SELECT * FROM users") fun getAllUsers(): LiveData<List<User>>. This ensures cursors are closed when lifecycle ends.
  2. If using raw Cursor, call cursor.close() in finally block and use ContentResolver.query with auto-close flag: val cursor = contentResolver.query(uri, null, null, null, null)?.use { it }

Dead Ends

Common approaches that don't work:

  1. Increasing heap size in AndroidManifest with android:largeHeap=true 90% fail

    Does not address cursor leak; heap size increase delays but doesn't prevent crash.

  2. Adding try-finally blocks around cursor usage without using Room's LiveData or Flow 70% fail

    Manual cursor management is error-prone; Room's reactive types handle lifecycle automatically.