与CursorLoader和MergeCursor一起使用分页会关闭旧的游标 [英] Using pagination with CursorLoader and MergeCursor closes old cursors

查看:353
本文介绍了与CursorLoader和MergeCursor一起使用分页会关闭旧的游标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如标题所述,当试图对由SimpleCursorAdapterCursorLoader支持的ListView进行分页时,旧的游标将关闭,因此将引发以下异常.前两个页面加载良好(第一个页面不使用MergeCursor,第二个页面是第一个使用MergeCursor的页面).我不会在任何光标上调用任何close().

As the title says, when trying to paginate a ListView backed by a SimpleCursorAdapter and a CursorLoader, old cursors are getting closed, thus the below exception is being thrown. The first 2 pages load just fine (the first isn't using the MergeCursor and the second page is the first one to use the MergeCursor). I don't call any close() on any cursor whatsoever.

有趣的是,在调试时,我看不到任何游标上的关闭标志都被设置为true,这是值得的.然后可能是MergeCursor的问题.让我知道你们是否有解决方案,我没有想法.

What is interesting is that while debugging, I cannot see the closed flags on any cursor being set as true, for what it's worth. Might be an issue with the MergeCursor then. Let me know if you guys have any solutions, I'm out of ideas.

堆栈跟踪:

android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method.
    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:139)
    at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:74)

代码:

private List<Cursor> mCursorsList = new ArrayList<>();

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
                     int visibleItemCount, int totalItemCount)
{
    if (!isLoading && !isAllLoaded &&
            firstVisibleItem != 0 &&
            firstVisibleItem == totalItemCount - visibleItemCount)
        getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
}

@Override
public void onLoadFinished(Loader<Cursor> loader, final Cursor data)
{
        Cursor oldCursor = mCursorAdapter.getCursor();
        mCursorsList.add(data);
        if (oldCursor != null)
        {
            Cursor[] cursorArray = mCursorsList.toArray(new Cursor[mCursorsList.size()]);
            MergeCursor newCursor = new MergeCursor(cursorArray);
            mCursorAdapter.swapCursor(newCursor);
        }
        else // first cursor
        {
            mCursorAdapter.swapCursor(data);
        }
}

@Override
public void onLoaderReset(Loader<Cursor> loader)
{
}

推荐答案

此问题的主要原因是CursorLoader管理内部游标,因此无论何时需要打开新游标(例如新页面查询) ),它将关闭旧的光标.

The main cause of this issue is that the CursorLoader manages the inner cursor, so whenever it needs to open a new one (such as a new page query), it closes the old cursor.

对于更简单的分页实现,不要使用偏移量查询,只需增加每页的限制,以便新光标也包含以前的所有页面.而且,正如伊恩·莱克(Ian Lake)在Google+上建议的那样,有时甚至不需要分页,尤其是在进行复杂的联接或对数据进行排序时.

For a more simple pagination implementation, don't query with offsets, just bump the limit on every page, so that the new cursor contains all previous pages as well. Also, as Ian Lake suggested on Google+, sometimes you don't even need pagination, especially if you are doing complicated joins or sorting the data.

这篇关于与CursorLoader和MergeCursor一起使用分页会关闭旧的游标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆