无法分配 CursorWindow
Posted
技术标签:
【中文标题】无法分配 CursorWindow【英文标题】:Could not allocate CursorWindow 【发布时间】:2013-07-03 23:02:24 【问题描述】:我在我的 android 应用程序中对 SQLite3 数据库进行操作。我刚刚从具有 200k 行和 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();
那么错误是什么意思,为什么应用程序崩溃了?
【问题讨论】:
完整的代码会很有帮助。您是否在自己管理后关闭光标,为什么不简单地调用 cursor.moveToNext() 而不是 !cursor.isAfterLast() 完整的应用程序代码为 1000 行。 cursor.isAfterLast 用于检查光标是否已在所有结果中移动,如果有,我可以停止。 你是否在 while 循环中关闭光标? 没有。忘记在上面的代码中粘贴该行。 【参考方案1】:错误 -12 表示游标泄漏。
尝试关闭它:
try .... finally cursor.close();
【讨论】:
我使用 Kotlinuse
方法,它会自动关闭所有内容,所以不,这是问题【参考方案2】:
我在一个循环中查询。并且在循环内部而不是外部关闭光标解决了这个问题。
【讨论】:
【参考方案3】:Android 游标将所有查询结果读入内存,并且该数据的大小限制为 1 MB。
之所以选择此限制,是因为此数据量可能会使您的应用在移动设备上运行缓慢。
如果可能,您应该:
不在您的代码中而是在 SQL 中进行计算; 仅查询您需要的数据(即,不要使用SELECT *
,而是只获取您需要的列,并使用WHERE
过滤器);
以较小的部分读取数据。
【讨论】:
这是不可能的。所有行在表中都是唯一的。所以一个查询只给出一个结果。 您肯定获得了不止一项记录。等价的SELECT COUNT(*) ...
的结果是什么?以上是关于无法分配 CursorWindow的主要内容,如果未能解决你的问题,请参考以下文章