База данных SQLite для базы данных SQLite с индексом 2048 кб не выполнена

У меня есть процедура, которая запускает разные запросы по базе данных SQLite много раз в секунду. Через некоторое время я получу ошибку

"android.database.CursorWindowAllocationException: - Cursor window allocation of 2048 kb failed. # Open Cursors = " появляется в LogCat.

У меня было использование памяти журнала приложений, и действительно, когда использование достигает определенного предела, я получаю эту ошибку, подразумевая, что она заканчивается. Моя интуиция подсказывает мне, что механизм базы данных создает новый буфер (CursorWindow) каждый раз, когда я запускаю запрос, и хотя я отмечаю курсоры .close (), ни сборщик мусора, ни SQLiteDatabase.releaseMemory() достаточно быстр на Освобождая память. Я думаю, что решение может заключаться в том, что «заставить» базу данных всегда записывать в один и тот же буфер, а не создавать новые, но я не смог найти способ сделать это. Я попытался создать экземпляр собственного CursorWindow и попытался установить его, а SQLiteCursor – безрезультатно.

Есть идеи?

EDIT: повторите запрос кода из @GrahamBorland:

 public static CursorWindow cursorWindow = new CursorWindow("cursorWindow"); public static SQLiteCursor sqlCursor; public static void getItemsVisibleArea(GeoPoint mapCenter, int latSpan, int lonSpan) { query = "SELECT * FROM Items"; //would be more complex in real code sqlCursor = (SQLiteCursor)db.rawQuery(query, null); sqlCursor.setWindow(cursorWindow); } 

В идеале я хотел бы иметь возможность .setWindow() перед тем, как дать новый запрос, и каждый раз, когда я получаю новые данные, данные помещаются в один и тот же CursorWindow .

Solutions Collecting From Web of "База данных SQLite для базы данных SQLite с индексом 2048 кб не выполнена"

Чаще всего причиной этой ошибки являются не закрытые курсоры. Убедитесь, что вы закрыли все курсоры после их использования (даже в случае ошибки).

 Cursor cursor = null; try { cursor = db.query(... // do some work with the cursor here. } finally { // this gets called even if there is an exception somewhere above if(cursor != null) cursor.close(); } 

Если вам нужно прорыть значительный объем кода SQL, вы можете ускорить отладку, поместив следующий фрагмент кода в свой MainActivity, чтобы включить StrictMode. Если обнаружены пропущенные объекты базы данных, ваше приложение теперь будет разбиваться с информацией о журнале, точно указывая, где находится ваша утечка. Это помогло мне найти курсора изгоев за считанные минуты.

 @Override protected void onCreate(Bundle savedInstanceState) { if (BuildConfig.DEBUG) { StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } super.onCreate(savedInstanceState); ... ... 

Я только что испытал эту проблему – и предлагаемый ответ не закрывать курсор в то время как действительный, не был тем, как я его исправил. Моя проблема заключалась в закрытии базы данных, когда SQLite пыталась переписать свой курсор. Я бы открыл базу данных, запросил базу данных, чтобы получить указатель на набор данных, закрыть базу данных и перебрать курсор. Я заметил, что всякий раз, когда я нажимаю определенную запись в этом курсоре, мое приложение рушится с той же ошибкой в ​​OP.

Я предполагаю, что для того, чтобы курсор получал доступ к определенным записям, ему необходимо повторно запросить базу данных, и если она будет закрыта, она будет вызывать эту ошибку. Я исправил его, не закрывая базу данных, пока не выполнил всю необходимую мне работу.