2

正如標題所示,當試圖對由SimpleCursorAdapterCursorLoader支持的ListView進行分頁時,舊的遊標正在關閉,因此會拋出以下異常。前兩頁加載得很好(第一頁不使用MergeCursor,第二頁是第一個使用MergeCursor)。我不會在任何光標上調用任何close()對CursorLoader和MergeCursor使用分頁關閉舊遊標

有趣的是,在調試過程中,我看不到任何光標被設置爲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) 
{ 
} 

回答

1

這個問題的主要原因是,CursorLoader管理內部光標,所以每當它需要打開一個新的一個(如新的頁面查詢),它會關閉舊的遊標。

爲了更簡單的分頁實現,不偏移查詢,只是碰到的每一頁上的限制,使新的遊標包含所有以前的頁面也是如此。另外,正如Ian Lake在Google+上所建議的那樣,有時候甚至不需要分頁,特別是在進行復雜的連接或排序數據的時候。