我目前正在安卓兼容性库的片段中使用一个CursorLoader。几乎每一次,在Droid 2上(我无法在Nexus One或感觉上复制),游标似乎关闭得太快,这导致了各种错误。不幸的是,这些跟踪在我的代码中并没有指出任何有用的地方(因为问题是为什么关闭游标,而不是当Android注意到时),所以我真的很难找出哪里出了问题。还有其他人遇到过这个问题吗?(或者有可能发生的事情)。
一些堆栈跟踪:
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 对于好的度量,在我的代码中至少有一行:
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) 更新:修正,见我在下面的答案
发布于 2011-07-05 13:26:01
我不知道问题出在哪里,但也许这能帮你把它固定下来。
创建这样的LoggedCursor并设置游标工厂,这样查询就可以为您提供LoggedCursor:
class LoggedCursor extends SQLiteCursor {
@Override
public void close() {
Log.d(TAG, "Cursor closed by:", new RuntimeException("Stack trace"));
super.close();
}
}创建RuntimeException只是为了轻松地记录堆栈跟踪,而不是为了抛出它。当游标关闭时,您将在日志中看到跟踪。
希望这有助于找出何时和由谁关闭。
发布于 2011-07-13 18:42:09
我按照JBM的建议添加了日志,并发现了以下内容:
我在代码中使用了CursorWrapper的子类。在Droid 2上,有人向CursorWrapper添加了一个终结器,它关闭了底层游标。这意味着每当垃圾收集包装器时,游标就会关闭。这个终结器不存在于其他手机或Android源代码中。你猜有人以为他们很聪明吗?
通过重写我们的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!
}https://stackoverflow.com/questions/6552405
复制相似问题