2012-09-29 2 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에서 그것을 닫을 수 있습니다() 메소드 : 내가 열고 시스템에 Cursors을 닫는 번거 로움을 떠나 startManagingCursor 방법에 의존하는 데 사용

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

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

. 이제는 더 이상 사용되지 않지만 여전히 사용은 권장되지 않습니다. 따라서 LoaderManager과 함께 CursorLoader 클래스를 사용하고 커서를 닫는 작업을 처리하는 시스템에 남겨 두십시오.

9

Cursor이 닫히기 때문에 오류가 발생합니다. 작성한 SimpleCursorAdapter은 여전히 ​​데이터에 액세스하려고 시도하고있을 수 있습니다.

CursorLoader을 사용하려는 경우 수행해야합니다.

  1. 이 클래스가 실제로 onCreateLoaderCursorLoader을 만들 LoaderManager.LoaderCallbacks<Cursor>
  2. 을 구현 적이
  3. 가 커서 널 (null)에 대한 참조를 사용하여 간단한 커서 어댑터를 만들기 변수 인스턴스로 어댑터에 대한 참조를 유지 onLoadFinished()에서
  4. onLoaderReset()에서 adapter.swapCursor(cursor)
  5. 으로 커서를 스왑이야 adapter.swapCursor로 null 커서 (널)`당신은 또한 컨텐트 프로에 데이터를 넣어 결국해야

로 커서를 WAP - 그것은 나쁜 아니에요!

관련 문제