2012-09-29 50 views
7

我想顯示一個列表視圖與名稱從我的數據庫中的對話框,但我不斷收到StaleDataException。我知道這通常意味着我試圖從一個封閉的遊標的數據,但直到我得到的所有數據,所以我不明白爲什麼我收到此StaleDataException與對話框

d = new Dialog(this); 
d.setContentView(R.layout.dialog_layout); 
d.setTitle("Select Bowler"); 

ListView lv = (ListView)d.findViewById(R.id.dialog_list); 
Cursor c = getContentResolver().query(
    BowlersDB.CONTENT_URI, 
    new String[] { 
     BowlersDB.ID, BowlersDB.FIRST_NAME, BowlersDB.LAST_NAME 
    }, 
    null, 
    null, 
    BowlersDB.LAST_NAME + " COLLATE LOCALIZED ASC" 
); 

if (c.moveToFirst() && c != null) { 
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(
     this, 
     R.layout.names_listview, 
     c, 
     new String[] { 
      BowlersDB.FIRST_NAME, BowlersDB.LAST_NAME 
     }, 
     new int[] { 
      R.id.bListTextView, R.id.bListTextView2 
     }, 
     0 
    ); 
    lv.setAdapter(adapter); 
    lv.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> arg0, View v, int position, long id) { 
      bowlerClickedID = id; 
      updateName(id); 
     } 
    }); 
    d.show(); 
} 
c.close(); 

錯誤

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.getString(AbstractWindowedCursor.java:50) 
    at android.database.CursorWrapper.getString(CursorWrapper.java:114) 
    at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:150) 
    at android.widget.CursorAdapter.getView(CursorAdapter.java:250) 
    at android.widget.AbsListView.obtainView(AbsListView.java:2267) 
    at android.widget.ListView.measureHeightOfChildren(ListView.java:1244) 
    at android.widget.ListView.onMeasure(ListView.java:1156) 
    at android.view.View.measure(View.java:15172) 
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390) 
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) 
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) 
    at android.view.View.measure(View.java:15172) 
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
    at android.view.View.measure(View.java:15172) 
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
    at android.view.View.measure(View.java:15172) 
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390) 
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) 
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) 
    at android.view.View.measure(View.java:15172) 
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148) 
    at android.view.View.measure(View.java:15172) 
    ... 
光標沒有關閉

編輯: 如果我註釋掉c.close()行它工作正常,但我不能讓光標打開,但我該怎麼辦?

回答

4

在CursorAdapter不再需要之前,您無法關閉遊標。所以,你可以在的onDestroy關閉它()方法:

@Override 
public void onDestroy() { 
super.onDestroy(); 

ListView lv = (ListView) d.findViewById(R.id.dialog_list); 
((CursorAdapter) lv.getAdapter()).getCursor().close(); 
database.close(); 
} 
0

我習慣了依賴startManagingCursor方法離開開閉Cursors到系統的麻煩。現在它已過時(它仍然有效,但我不推薦使用它),請考慮使用CursorLoader類和LoaderManager,並將其留給系統以處理光標關閉。

9

由於您正在關閉Cursor而您創建的SimpleCursorAdapter可能仍然試圖從中訪問數據,因此您會收到錯誤消息。

如果你想使用CursorLoader,你應該這樣做。

  1. 保持到您的適配器的引用作爲一個實例變量
  2. 與基準爲null的光標創建簡單的遊標適配器
  3. 有你的類實現LoaderManager.LoaderCallbacks<Cursor>
  4. onCreateLoader實際創建CursorLoader
  5. onLoadFinished()中,將遊標與adapter.swapCursor(cursor)
  6. 對換
  7. onLoaderReset()中,s WAP光標用null光標爲adapter.swapCursor(空)`

你也應該結束了把你的數據在ContentProvider的 - 它不是那麼糟糕!