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)
{
}
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.
来源:https://stackoverflow.com/questions/34828657/using-pagination-with-cursorloader-and-mergecursor-closes-old-cursors