Android SQLite CursorWindowAllocationException崩溃

5

我有一个情况,在我执行多个cursor.moveToNext()请求时,我的程序会崩溃。错误信息如下:

android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=773 (# cursors opened by this proc=773)
at android.database.CursorWindow.<init>(CursorWindow.java:112)
at android.database.CursorWindow.<init>(CursorWindow.java:100)
at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
at android.database.sqlite.SQLiteCursor.clearOrCreateWindow(SQLiteCursor.java:364)
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.moveToNext(AbstractCursor.java:209)
at net.cunniman.teacherplannerlite.SchoolClassDataSource.getClassForDayView(SchoolClassDataSource.java:173)
at net.cunniman.teacherplannerlite.DayView.getSchoolClasses(DayView.java:200)
at net.cunniman.teacherplannerlite.DayView.displayDate(DayView.java:176)
at net.cunniman.teacherplannerlite.DayView.plusDay(DayView.java:287)
at net.cunniman.teacherplannerlite.DayView.onClick(DayView.java:93)
at android.view.View.performClick(View.java:3565)
at android.view.View$PerformClick.run(View.java:14165)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4514)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
at dalvik.system.NativeStart.main(Native Method)

try {
    this.openForRead();
    for (int day_counter = 0; day_counter < DAY_PERIOD.length/2; day_counter++)
    {
        Cursor cursor = database.rawQuery
            ("SELECT " + NAME + " FROM " + TABLE_NAME + " WHERE " + DAY_PERIOD[day_counter * 2]
            + " = '" + day + "' AND " + DAY_PERIOD[day_counter * 2 + 1] + " = "
            + Integer.toString(period), null);


    while (cursor.moveToNext())
    {
        String name = cursor.getString(0);
        sc.setName(name);
    }


} finally {
    this.close();
}

有人知道可能是什么原因导致这个问题吗?看起来像是内存泄漏(也许?),但我能采取什么措施来防止它发生吗?

谢谢


你可能没有关闭所有的游标。 - nandeesh
2
你没有关闭所有的游标。在 while 循环之后,添加 cursor.close。你还创建了许多 Cursor 对象。我建议您检查一下代码。最好执行“更大”的 SQL,提取所有数据,然后对其进行循环处理。 - Tom
谢谢Tom,这对我非常有帮助,很有道理。我明天会尝试实现。 - Mark__C
我有一个类似的问题,在模拟器上发生,但在我测试过的任何设备上都没有发生。然而,我正在关闭所有的光标。你有什么想法吗? - Michell Bak
1个回答

8

这种错误通常是由于未关闭游标造成的。确保在使用完毕后关闭所有游标(即使在出现错误的情况下也要关闭)。

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

我遇到了一个类似的问题,它只在模拟器上出现,而在我测试过的任何设备上都没有出现。然而,我已经关闭了所有的游标。你有什么想法吗? - Michell Bak
抱歉,没有具体的细节我无法提供帮助。最好开一个新问题来询问。 - whlk
是的,我有这种感觉。在我这种情况下,这是一个非常复杂的问题,所以我要先重新编写所有的代码,看看是否有帮助。 - Michell Bak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接