android - 在 onLoadFinished() 期间合并游标会在旋转后导致 StaleDataException

标签 android staledataexception matrixcursor mergecursor

我正在使用 loaderManager 从数据库中加载一些结果。不幸的是,以下代码在旋转设备后产生了 StaleDataException:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
{
    // If we've returned results, then pass them and the webSearches cursor along to be displayed
    if(cursor.moveToFirst())
    {
        // Get a cursor containing additional web searches and merge it at the end of the results cursor 
        MatrixCursor searchesCursor = getWebSearchesCursor(searchTerm, false);
        Cursor[] cursors = { cursor, searchesCursor };
        // TODO: Figure out why merging cursors here causes staledataexception after rotation
        Cursor results = new MergeCursor(cursors);
        // Display the cursor in the ListView
        adapter.changeCursor(results);
    }
    // If no results were returned, then return suggestions for web searches
    else
    {
        // Get a cursor containing additional web searches 
        MatrixCursor noResults = getWebSearchesCursor(searchTerm, true);
        adapter.changeCursor(noResults);    
    }

    // Show the listView and hide the progress spinner
    toggleListView(SHOW);
}

调用 getWebSearchesCursor() 会返回一个 MatrixCursor 以及一些附加的搜索提示,以伴随任何返回的结果。我发现将 adapter.changeCursor(results) 更改为 adapter.changeCursor(cursor) 可以修复错误,因此看起来将 MatrixCursor 合并到返回的游标会产生错误。

我的问题是,为什么?

如果返回任何结果,我希望能够向返回的游标添加其他项目,以便用户可以选择在几个网站上执行搜索。有没有更好的方法来合并游标,以便在旋转后不会出现此异常?

最佳答案

如果您已经开始在所有地方使用 swapCursor() 而不是 changeCursor(),那么我希望您也已经开始在这些地方处理游标关闭。

changeCursor() 将关闭旧游标,这是有意为之的,当您直接使用 onLoadFinished() 提供的游标时可以完美地工作。它以这种方式完成,因此您不必担心关闭它。

当您旋转设备时,android 系统会检查上次发送给您的光标是否尚未关闭,然后再次发送,而不是花费资源创建一个新的。您的代码将此光标包装在 MergeCursor新实例中,该实例被传递给 changeCursor(),它会发现这不是同一个对象它之前得到,并决定关闭旧实例。由于 MergeCursor 仅包装您传递给它的游标,而不是复制其中的数据,因此您的新实例现在(至少)包含一个关闭的游标。

要正确处理这个问题,您需要自己编写一些代码来检查您通过 onLoadFinished() 获得的光标是否与您当前的 MergeCursor 中的光标相同 实例,并且只有在获得新游标时才关闭现有实例。当然,您还需要跟踪包含在同一 MergeCursor 实例中的其他游标。

关于android - 在 onLoadFinished() 期间合并游标会在旋转后导致 StaleDataException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16392692/

相关文章:

java - Hibernate 在调用 findOne 时返回陈旧的对象

android - 带有对话框的 StaleDataException

java - 通过内容提供者传递二进制 blob

android - 具有非数据库内容提供者的 Matrixcursor

android - SearchView:从建议监听器中获取选中的项目

隐藏 Python Kivy TextInputs 的 Android 屏幕键盘

javascript - Android_Studio 错误

android - 检查 View 是否属于线性布局

android - 动态资源加载 Android

android - 除了过早调用 cursor.close() 之外还有什么会导致 StaleDataException?