Biblioteca de Compatibilidad de Android CursorLoader: java.lang.IllegalStateException: Cursor is closed

Actualmente utilizo un CursorLoader dentro de un Fragmento con la Biblioteca de Compatibilidad de Android. Casi cada vez, en el Droid 2 (no puedo reproducir en el Nexus One o la sensación), parece que los cursores se están cerrando demasiado pronto, lo que está causando varios errores. Desafortunadamente las huellas no apuntan a ninguna parte útil en mi código (ya que el problema es por qué el Cursor se está cerrando, no cuando los avisos de Android), así que estoy realmente luchando para averiguar qué está yendo mal. ¿Alquien más se ha encontrado con este problema? (O tener ideas de lo que podría estar pasando).

Algunos rastros de la pila:

java.lang.IllegalStateException: Cursor is closed at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:278) at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:255) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:187) at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:187) at android.support.v4.widget.CursorAdapter.getItemId(CursorAdapter.java:226) at android.widget.AbsListView$PerformClick.run(AbsListView.java:1721) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:143) at android.app.ActivityThread.main(ActivityThread.java:4717) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) at dalvik.system.NativeStart.main(Native Method) java.lang.IllegalStateException: Cursor is closed at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:278) at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:255) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:187) at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:187) at android.support.v4.widget.CursorAdapter.getItemId(CursorAdapter.java:226) at android.widget.AdapterView.getItemIdAtPosition(AdapterView.java:745) at android.widget.AdapterView.setSelectedPositionInt(AdapterView.java:1081) at android.widget.AbsListView.onTouchEvent(AbsListView.java:2207) at android.widget.ListView.onTouchEvent(ListView.java:3377) at android.view.View.dispatchTouchEvent(View.java:3766) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1800) at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1140) at android.app.Activity.dispatchTouchEvent(Activity.java:2105) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1784) at android.view.ViewRoot.handleMessage(ViewRoot.java:1794) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:143) at android.app.ActivityThread.main(ActivityThread.java:4717) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) at dalvik.system.NativeStart.main(Native Method) java.lang.RuntimeException: Unable to pause activity : java.lang.IllegalStateException: Cursor is closed at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3438) at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3395) at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3378) at android.app.ActivityThread.access$2700(ActivityThread.java:129) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2124) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:143) at android.app.ActivityThread.main(ActivityThread.java:4717) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalStateException: Cursor is closed at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:278) at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:255) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:187) at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:187) at android.support.v4.widget.CursorAdapter.getItemId(CursorAdapter.java:226) at android.widget.AbsListView.onSaveInstanceState(AbsListView.java:910) at android.widget.ListView.onSaveInstanceState(ListView.java:3687) at android.view.View.dispatchSaveInstanceState(View.java:6070) at android.view.ViewGroup.dispatchFreezeSelfOnly(ViewGroup.java:1197) at android.widget.AdapterView.dispatchSaveInstanceState(AdapterView.java:759) at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:1184) at android.view.View.saveHierarchyState(View.java:6053) at android.support.v4.app.FragmentManagerImpl.saveFragmentViewState(FragmentManager.java:1387) at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1439) at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:468) at android.app.Activity.performSaveInstanceState(Activity.java:1040) at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1180) at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3420) ... 12 more 

Y por buenas medidas, que al menos tiene una sola línea en mi código:

 android.database.StaleDataException: Access closed cursor at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:217) at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:27) at android.database.CursorWrapper.getBlob(CursorWrapper.java:143) at android.database.CursorWrapper.getBlob(CursorWrapper.java:143) at com.testapp.TestFragment$1.setViewValue(TestFragment.java:84) at android.support.v4.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:131) at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:257) at android.widget.AbsListView.obtainView(AbsListView.java:1319) at android.widget.ListView.makeAndAddView(ListView.java:1789) at android.widget.ListView.fillDown(ListView.java:656) at android.widget.ListView.fillSpecific(ListView.java:1342) at android.widget.ListView.layoutChildren(ListView.java:1616) at android.widget.AbsListView.onLayout(AbsListView.java:1172) at android.view.View.layout(View.java:7037) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at android.view.View.layout(View.java:7037) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at android.view.View.layout(View.java:7037) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125) at android.widget.LinearLayout.onLayout(LinearLayout.java:1042) at android.view.View.layout(View.java:7037) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at android.view.View.layout(View.java:7037) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at android.view.View.layout(View.java:7037) at android.view.ViewRoot.performTraversals(ViewRoot.java:1054) at android.view.ViewRoot.handleMessage(ViewRoot.java:1736) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:143) at android.app.ActivityThread.main(ActivityThread.java:4717) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) at dalvik.system.NativeStart.main(Native Method) 

Actualización: fijo, ver mi respuesta a continuación

2 Solutions collect form web for “Biblioteca de Compatibilidad de Android CursorLoader: java.lang.IllegalStateException: Cursor is closed”

No tengo idea de cuál es el problema, pero tal vez esto le ayuda a fijarlo.

Crear un LoggedCursor como este y configurar el cursor de fábrica para que su consulta le da el LoggedCursor:

 class LoggedCursor extends SQLiteCursor { @Override public void close() { Log.d(TAG, "Cursor closed by:", new RuntimeException("Stack trace")); super.close(); } } 

La RuntimeException se crea sólo para registrar el seguimiento de la pila fácilmente, no para lanzarla. Cuando el cursor está cerrado verá el rastreo en registros.

Esperemos que esto ayude a averiguar cuándo y por quién está cerrado.

He agregado el registro según la sugerencia de JBM y encontré lo siguiente:

Yo estaba usando una subclase de CursorWrapper en mi código. En el Droid 2, alguien agregó un finalizador a CursorWrapper que cierra el cursor subyacente. Eso significaba que siempre que nuestro envoltorio fuera recogido de basura, el Cursor estaba cerrado. Este finalizador no existe en otros teléfonos ni en el código fuente de Android. Supongo que alguien pensó que estaban siendo inteligentes?

Corregido anulando el finalizador en nuestro CursorWrapper

 protected void finalize() throws Throwable { // Do not remove this empty method. It is designed to prevent calls to super. // Fixes bug on Droid 2, where CursorWrapper finalizer closes the Cursor! } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.