2012-09-29 16 views
7

Sto tentando di mostrare una finestra di dialogo con un listview con i nomi dal mio database ma continuo a ricevere StaleDataException. So che di solito significa che sto cercando di utilizzare i dati da un cursore chiuso ma il cursore non si chiude fino a ottenere tutti i dati così io non capisco perché sto ottenendo questoStaleDataException con finestra di dialogo

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

errore

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

MODIFICA: Se commento la riga c.close() funziona correttamente ma non posso lasciare il cursore aperto, quindi cosa devo fare?

risposta

4

Non è possibile chiudere il cursore finché CursorAdapter non è più necessario. Così si può chiuderlo in OnDestroy() metodo:

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

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

ho usato per contare su startManagingCursor metodo per lasciare il fastidio di apertura e chiusura Cursors al sistema. Ora che è deprecato (funziona ancora ma non lo consiglierei di usarlo), considera l'utilizzo della classe CursorLoader con LoaderManager e lascialo al sistema per gestire la chiusura del Cursore.

9

Hai ricevuto il tuo errore perché stai chiudendo lo Cursor mentre il SimpleCursorAdapter che hai creato potrebbe ancora provare ad accedere ai dati da esso.

Se si desidera utilizzare uno CursorLoader, come si dovrebbe fare.

  1. Mantenere un riferimento al vostro adattatore come un'istanza variabile
  2. Creare il vostro adattatore del cursore semplice con un riferimento nullo per il cursore
  3. Avere la classe implementare LoaderManager.LoaderCallbacks<Cursor>
  4. In realtà creare il CursorLoader nel onCreateLoader
  5. In onLoadFinished(), scambiare i cursori con adapter.swapCursor(cursor)
  6. In onLoaderReset(), s WAP il cursore con un null cursore come adapter.swapCursor (null) `

Si dovrebbe anche finire per mettere i dati in un ContentProvider - non è poi così male!

Problemi correlati