Я работаю в базе данных SQLite3 в своем приложении для Android. Я просто прочитал из предварительно заполненной базы данных, которая имеет 200 тыс. Строк и 14 столбцов. Записи – это слова. Тип данных всех столбцов – это текст. Запрос слов до 11 букв (например, ABANDONMENT) работает нормально. Но на 12 или больше (например, ABANDONMENTS) приложение выйдет из строя. Вот logcat:
Could not allocate CursorWindow '//data//data//com.example.myapp//databases//database.sqlite' of size 2097152 due to error -12. threadid=11: thread exiting with uncaught exception (group=0x40adf9f0) FATAL EXCEPTION: Thread-2883 android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=861 (# cursors opened by this proc=861) at android.database.CursorWindow.<init>(CursorWindow.java:104) at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198) at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:162) at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:156) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:161) at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:201) at com.example.myapp.MainActivity.query(MainActivity.java:815) at com.example.myapp.MainActivity$2.run(MainActivity.java:356) at java.lang.Thread.run(Thread.java:856)
код:
query = "select * from words where col_1 = \"" + (myWord)+ "\";"; cursor = database.rawQuery(query, null); if (cursor != null) cursor.moveToFirst(); // line 815 if (!cursor.isAfterLast()) { do { for (i = 1; i < cursor.getColumnCount(); i++) { temp = cursor.getString(i); //other stuff } } while (cursor.moveToNext()); cursor.close(); }
Итак, что означает ошибка и почему приложение сбой?
Ошибка -12 означает утечку курсора. Pls попробуйте закрыть его следующим образом:
try {....} finally { cursor.close();}
Я просыпался в петле. И закрытие курсора внутри цикла, а не вне решения проблемы.
Курсоры Android считывают все результаты запроса в память и имеют ограничение в 1 МБ для этих данных.
Этот лимит был выбран, потому что этот объем данных, скорее всего, заставит ваше приложение работать вяло на мобильном устройстве.
Вы должны, если это возможно:
SELECT *
а получать только нужные столбцы и использовать фильтр WHERE
);