Android 对游标加载程序和合并游标使用分页关闭旧游标

Android 对游标加载程序和合并游标使用分页关闭旧游标,android,loader,simplecursoradapter,android-cursor,android-cursorloader,Android,Loader,Simplecursoradapter,Android Cursor,Android Cursorloader,正如标题所述,当尝试对由SimpleCorsorAdapter和CursorLoader支持的ListView进行分页时,旧的游标将被关闭,因此引发下面的异常。前两个页面加载得很好(第一个页面没有使用MergeCursor,第二个页面是第一个使用MergeCursor)。我不会在任何游标上调用任何close() 有趣的是,在调试时,我看不到任何游标上的关闭标志被设置为true,这是值得的。那么,MergeCursor可能有问题。如果你们有什么解决办法,请告诉我,我没有主意了 堆栈跟踪: andr

正如标题所述,当尝试对由
SimpleCorsorAdapter
CursorLoader
支持的
ListView
进行分页时,旧的游标将被关闭,因此引发下面的异常。前两个页面加载得很好(第一个页面没有使用
MergeCursor
,第二个页面是第一个使用
MergeCursor
)。我不会在任何游标上调用任何
close()

有趣的是,在调试时,我看不到任何游标上的关闭标志被设置为true,这是值得的。那么,
MergeCursor
可能有问题。如果你们有什么解决办法,请告诉我,我没有主意了

堆栈跟踪:

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)
{
}
代码:

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)
{
}
private List mCursorsList=new ArrayList();
@凌驾
public void onScroll(AbsListView视图,int firstVisibleItem,
int visibleItemCount,int totalItemCount)
{
如果(!isLoading&&!已全部加载&&
firstVisibleItem!=0&&
firstVisibleItem==totalItemCount-visibleItemCount)
getActivity().getSupportLoaderManager().restartLoader(LOADER_ID,null,this);
}
@凌驾
public void onLoadFinished(加载程序,最终光标数据)
{
Cursor oldCursor=mCursorAdapter.getCursor();
mCursorsList.add(数据);
if(oldCursor!=null)
{
游标[]cursorArray=mCursorsList.toArray(新游标[mCursorsList.size()]);
MergeCursor newCursor=新的MergeCursor(cursorArray);
mCursorAdapter.swapCursor(newCursor);
}
else//第一个光标
{
mCursorAdapter.swapCursor(数据);
}
}
@凌驾
公共void onLoaderReset(加载器)
{
}

此问题的主要原因是
游标加载程序管理内部游标,因此每当需要打开新游标(例如新页面查询)时,它都会关闭旧游标

对于更简单的分页实现,不要使用偏移量进行查询,只需在每个页面上增加限制,以便新的游标也包含所有以前的页面。此外,正如Ian Lake在Google+上建议的那样,有时甚至不需要分页,尤其是在进行复杂的连接或数据排序时