2012-09-29 33 views
7

Tôi đang cố gắng hiển thị một hộp thoại với một listview với tên từ cơ sở dữ liệu của tôi nhưng tôi tiếp tục nhận được một StaleDataException. Tôi biết rằng thường có nghĩa là tôi đang cố gắng sử dụng dữ liệu từ một con trỏ khép kín nhưng con trỏ không đóng cho đến khi tôi nhận được tất cả các dữ liệu vì vậy tôi không hiểu tại sao tôi nhận được nàyStaleDataException với hộp thoại

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(); 

lỗi

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) 
    ... 

EDIT: Nếu tôi nhận xét ra dòng c.close() nó hoạt động tốt nhưng tôi không thể chỉ để con trỏ mở mặc dù vậy tôi phải làm gì?

Trả lời

4

Bạn không thể đóng con trỏ cho đến khi CursorAdapter không còn cần thiết nữa. Vì vậy, bạn có thể đóng nó trong onDestroy() phương pháp:

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

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

Tôi đã từng phải dựa vào startManagingCursor phương pháp rời khỏi những rắc rối của việc đóng mở Cursors vào hệ thống. Bây giờ nó không được chấp nhận (nó vẫn hoạt động nhưng tôi sẽ không khuyên bạn nên sử dụng nó), hãy xem xét sử dụng lớp CursorLoader với LoaderManager và để nó vào hệ thống để xử lý đóng con trỏ.

9

Bạn nhận được lỗi của mình vì bạn đang đóng Cursor trong khi SimpleCursorAdapter bạn tạo có thể vẫn đang cố truy cập dữ liệu từ đó.

Nếu bạn muốn sử dụng CursorLoader, như bạn nên làm.

  1. Giữ một tham chiếu đến bộ chuyển đổi của bạn như là một ví dụ biến
  2. Tạo bộ chuyển đổi con trỏ đơn giản của bạn với một tham chiếu đến null cho con trỏ
  3. có lớp học của bạn thực hiện LoaderManager.LoaderCallbacks<Cursor>
  4. Trên thực tế tạo ra CursorLoader trong onCreateLoader
  5. Trong onLoadFinished(), hoán đổi con trỏ với adapter.swapCursor(cursor)
  6. Trong onLoaderReset(), s wap con trỏ với con trỏ null dưới dạng adapter.swapCursor (null) `

Bạn cũng nên kết thúc việc đưa dữ liệu của mình vào Trình cung cấp nội dung - không phải là xấu!