StaleDataException con diálogo
Estoy intentando demostrar un diálogo con un listview con nombres de mi base de datos pero sigo recibiendo un StaleDataException
. Sé que por lo general significa que estoy tratando de utilizar los datos de un cursor cerrado, pero el cursor no se cierra hasta que reciba todos los datos por lo que no entiendo por qué estoy recibiendo este
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();
error
09-29 13:11:47.333: E/AndroidRuntime(20605): android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method. 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:139) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.database.CursorWrapper.getString(CursorWrapper.java:114) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:150) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.CursorAdapter.getView(CursorAdapter.java:250) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.AbsListView.obtainView(AbsListView.java:2267) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.ListView.measureHeightOfChildren(ListView.java:1244) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.ListView.onMeasure(ListView.java:1156) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.View.measure(View.java:15172) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.View.measure(View.java:15172) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.View.measure(View.java:15172) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.View.measure(View.java:15172) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.View.measure(View.java:15172) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 09-29 13:11:47.333: E/AndroidRuntime(20605): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.View.measure(View.java:15172) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1848) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1075) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1273) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.Choreographer.doCallbacks(Choreographer.java:555) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.Choreographer.doFrame(Choreographer.java:525) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.os.Handler.handleCallback(Handler.java:615) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.os.Handler.dispatchMessage(Handler.java:92) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.os.Looper.loop(Looper.java:137) 09-29 13:11:47.333: E/AndroidRuntime(20605): at android.app.ActivityThread.main(ActivityThread.java:4745) 09-29 13:11:47.333: E/AndroidRuntime(20605): at java.lang.reflect.Method.invokeNative(Native Method) 09-29 13:11:47.333: E/AndroidRuntime(20605): at java.lang.reflect.Method.invoke(Method.java:511) 09-29 13:11:47.333: E/AndroidRuntime(20605): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 09-29 13:11:47.333: E/AndroidRuntime(20605): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 09-29 13:11:47.333: E/AndroidRuntime(20605): at dalvik.system.NativeStart.main(Native Method)
EDIT: Si comento la línea c.close()
funciona bien, pero no puedo dejar el cursor abierto, así que ¿qué debo hacer?
No puede cerrar el cursor hasta que CursorAdapter ya no sea necesario. Así que puedes cerrarlo en el método onDestroy ():
@Override public void onDestroy() { super.onDestroy(); ListView lv = (ListView) d.findViewById(R.id.dialog_list); ((CursorAdapter) lv.getAdapter()).getCursor().close(); database.close(); }
Usted está recibiendo su error porque está cerrando el Cursor
mientras que el SimpleCursorAdapter
que cree todavía podría estar tratando de acceder a los datos de él.
Si quieres usar un CursorLoader
, como deberías hacer.
- Mantenga una referencia a su adaptador como una variable de instancia
- Cree su adaptador de cursor simple con una referencia a null para el cursor
- Haga que su clase implemente
LoaderManager.LoaderCallbacks<Cursor>
- Realmente crear el
CursorLoader
en elonCreateLoader
- En
onLoadFinished()
, intercambie los cursores conadapter.swapCursor(cursor)
- En
onLoaderReset()
, intercambie el cursor con un cursornull
como adapter.swapCursor (null) `
También debe terminar poniendo sus datos en un ContentProvider – no es tan malo!
Solía confiar en el método startManagingCursor
para dejar la molestia de abrir y cerrar Cursors
al sistema. Ahora que está obsoleto (todavía funciona pero no recomendaría usarlo), considere el uso de la clase LoaderManager
con LoaderManager
y déjelo al sistema para manejar el cierre del Cursor.