2012-09-29 35 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的 - 它不是那么糟糕!