java.lang.IllegalStateException: 无法从CursorWindow中读取第x行第x列的数据。请确保Cursor已正确初始化。联系人

6
我已经开发了一个应用程序,可以浏览 Android 上的所有联系人。该应用程序已经发布,并且目前已安装在大约 800 台设备上。它几乎可以在所有设备上运行而不会出现任何问题,但是在某些设备上,我通过 BugSense 收到了错误信息,但我尚未找到有效的解决方案。
以下是我得到的其中一个堆栈跟踪:
java.lang.IllegalStateException: Couldn't read row 0, col 8 from CursorWindow. Make sure the Cursor is     initialized correctly before accessing data from it.
at android.os.Parcel.readException(Parcel.java:1335)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:182)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:136)
at android.database.BulkCursorProxy.getWindow(BulkCursorNative.java:192)
at android.database.BulkCursorToCursorAdaptor.onMove(BulkCursorToCursorAdaptor.java:94)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:178)
at android.database.AbstractCursor.moveToNext(AbstractCursor.java:209)
at android.database.CursorWrapper.moveToNext(CursorWrapper.java:166)
at de.android.contactscleaner.ContactsActivity.deleteContacts(ContactsActivity.java:118)
at de.android.contactscleaner.ContactsActivity$1.run(ContactsActivity.java:61)
at java.lang.Thread.run(Thread.java:856)

在我的代码中,在访问光标之前,我会执行以下操作,这也是解决方案的一部分:
    private void initCursor() {
    cr = getContentResolver();

    if (cr != null) {
        cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null,
                null, null);

    }
}

private void retryCursorInitialisation() {

    while (attempt < Rules.cursor_init_attempts) {
        attempt++;
        initCursor();
        // Check if cursor is initialisated correctly
        if (cur != null && cur.getColumnCount() != 0) {
            if (attempt >= Rules.cursor_init_attempts_to_report) {
                BugSenseHandler.sendEvent("Cursor init succeded after "
                        + attempt + "/" + Rules.cursor_init_attempts
                        + " retries");
            }
            break;
        } else {
            if (attempt == Rules.cursor_init_attempts) {
                BugSenseHandler
                        .sendEvent("Cursor init completly failed after "
                                + attempt + " attempts");
            }
        }

    }
}

如果光标“损坏”,它永远不会重新初始化,因为cur.getColumCount()从不为0。

(我在stackoverflow的另一个帖子中读到,应该检查列计数是否为0,而不是检查游标是否为空,但这并不起作用。这意味着,确实只有某些列/行存在问题。

错误发生的部分很简单:

        while (cur.moveToNext())

编辑:

出现问题的部分周围的完整代码段:

        if (cur != null && cur.getColumnCount() != 0) {
        try {
            cur.moveToFirst();
        } catch (Exception e) {
            initCursor();
        }

        while (cur.moveToNext()) ....

请帮助我,我的评分越来越差,但我无能为力。

2个回答

2
似乎这可能与提交给Google的错误相关:http://code.google.com/p/android/issues/detail?id=32472。它说已经分配,但自去年以来我没有看到任何活动。
(根据错误,您是否正在更新支持DB表中的任何行,这将导致在更新CursorWindow时行计数不同?)

2
尝试使用 moveToFirst 来定位光标,并在尝试读取任何数据之前检查其计数,以确保它不为空。

啊,抱歉,我没有提到。在移动光标之前,我已经这样做了。我刚刚将其添加到主帖中。 - Marian Klühspies
你仍然缺少光标计数检查 - 光标可能为空,因此不会moveToNext - Asahi
啊,好的,那就不用 cursor.getColumnCount() 了,直接用 cursor.getCount() 就可以了?你有没有想过如何重现这个错误并检查解决方案是否有效呢? - Marian Klühspies
通过删除所有联系人或添加一些错误条件,使您的查询返回空游标,即什么也不返回。 - Asahi
好的,谢谢。我会推送一个更新,希望我再也不会看到这个错误了 :) - Marian Klühspies
1
更新已发布,但我仍然遇到完全相同的错误,即使在之前检查计数是否大于零。但现在至少我捕获了这个错误,所以应用程序不会崩溃。我无法解决它... :( - Marian Klühspies

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