2012-09-29 8 views
7

Próbuję wyświetlić okno dialogowe z widokiem listy z nazwami z mojej bazy danych, ale nadal otrzymuję numer StaleDataException. Wiem, że zwykle oznacza Staram się wykorzystywać dane z zamkniętego kursorem ale kursor nie zamyka, dopóki nie dostanę wszystkie dane, więc nie rozumiem, dlaczego jestem coraz toWyjątek StaleDataException z dialogiem

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

błąd

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

EDYTOWANIE: Jeśli skomentuję linię c.close() działa dobrze, ale nie mogę po prostu pozostawić kursora otwartego, więc co mam zrobić?

Odpowiedz

4

Nie można zamknąć kursora, dopóki CursorAdapter nie będzie już potrzebny. Metoda, dzięki czemu można go zamknąć w onDestroy():

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

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

kiedyś polegać na startManagingCursor metody pozostawić kłopotów z otwarciem i zamknięciem Cursors do systemu. Teraz, gdy jest przestarzałe (nadal działa, ale nie polecam go używać), rozważ użycie klasy CursorLoader z LoaderManager i pozostaw to w systemie, aby obsłużyć zamknięcie kursora.

9

Otrzymujesz błąd, ponieważ zamykasz kod Cursor, podczas gdy utworzony SimpleCursorAdapter może nadal próbować uzyskać dostęp do danych z niego.

Jeśli chcesz użyć CursorLoader, tak jak powinieneś.

  1. przechowują odniesienia do karty jako instancja zmiennej
  2. Tworzenie prostego adaptera kursora z odniesieniem do null dla kursora
  3. Czy klasa wdrożenia LoaderManager.LoaderCallbacks<Cursor>
  4. Właściwie stworzyć CursorLoader w onCreateLoader
  5. W onLoadFinished() przestaw kursory z adapter.swapCursor(cursor)
  6. W onLoaderReset(), s WAP kursor z null kursora jako adapter.swapCursor (null) `

Należy także skończyć umieszczenie swoich danych w ContentProvider - to nie jest tak źle!

Powiązane problemy