I’m currently using a CursorLoader inside a Fragment with the Android Compatibility Library.
Almost every time, on the Droid 2 (I’m unable to reproduce on the Nexus One or the Sensation), it seems that the cursors are being closed too soon, which is causing various errors. Unfortunately the traces don’t point anywhere helpful in my code (since the issue is why the Cursor is being closed, not when Android notices), so I’m really struggling to figure out what is going wrong. Has anyone else encountered this problem? (or have ideas what might be happening).
Some stack traces:
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
And for good measures, one that at least has a single line in my code:
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)
Update: Fixed, see my answer below
I have no cue what the problem is, but maybe this helps you pinning it down.
Create a
LoggedCursorlike this and setup cursor factory so your query gives you the LoggedCursor:The
RuntimeExceptionis created just to log the stack trace easily, not for throwing it. When the cursor is closed you’ll see the trace in logs.Hopefully, this helps figuring out when and by whom is it closed.