ITKeyword,专注技术干货聚合推荐

注册 | 登录

解决android - Using pagination with CursorLoader and MergeCursor closes old cursors

itPublisher 分享于

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

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.

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.

Stack Trace:

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)

Code:

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)
{
}
android loader simplecursoradapter android-cursor android-cursorloader
|
  this question
edited Jan 17 '16 at 17:59 asked Jan 16 '16 at 15:24 Andrew 3,084 5 29 56

 | 

1 Answers
1

解决方法

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.

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.


|
  this answer
answered Jan 17 '16 at 23:52 Andrew 3,084 5 29 56

 | 


相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。