【问题标题】:Honeycomb and cursors蜂窝和游标
【发布时间】:2022-02-04 04:15:14
【问题描述】:

我有这个活动完全转换为使用蜂窝。我重新设计了所有游标管理以使用新的 cursorLoader。一切都适用于所有其他操作系统版本(使用兼容性库),但仍然不适用于蜂窝。以下堆栈跟踪非常难以理解,因为它没有告诉我哪个游标或哪一行失败。此外,在调试时,ParentActivity 中的任何代码行都不会被执行。当我恢复 ParentActivity 时发生此错误。当我开始活动时效果很好,但在返回时失败。

05-29 17:23:32.978: ERROR/AndroidRuntime(31692): FATAL EXCEPTION: main
05-29 17:23:32.978: ERROR/AndroidRuntime(31692): java.lang.RuntimeException: Unable to resume activity {com.xxx.xxx/com.xxx.xxx.ParentActivity}: java.lang.IllegalStateException: trying to requery an already closed cursor
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2227)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2255)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1028)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.os.Looper.loop(Looper.java:132)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.app.ActivityThread.main(ActivityThread.java:4025)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at java.lang.reflect.Method.invokeNative(Native Method)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at java.lang.reflect.Method.invoke(Method.java:491)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at dalvik.system.NativeStart.main(Native Method)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692): Caused by: java.lang.IllegalStateException: trying to requery an already closed cursor
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.app.Activity.performRestart(Activity.java:4394)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.app.Activity.performResume(Activity.java:4420)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2217)
05-29 17:23:32.978: ERROR/AndroidRuntime(31692):     ... 10 more

【问题讨论】:

    标签: android android-cursor android-3.0-honeycomb


    【解决方案1】:

    我遇到了同样的问题。这是我所做的。在我称为 startManagingCursor 的所有活动中,我将其覆盖为:

    @Override
    public void startManagingCursor(Cursor c) {
    
        // To solve the following error for honeycomb:
        // java.lang.RuntimeException: Unable to resume activity 
        // java.lang.IllegalStateException: trying to requery an already closed cursor
        if (Build.VERSION.SDK_INT < VersionUtil.HONEYCOMB) {
            super.startManagingCursor(c);
        }
    }
    

    这使我的应用可以在 Honeycomb 和更早版本上正确运行。

    【讨论】:

    • 删除 startManagingCursor 也为我解决了这个问题。使用 managedQuery 时,我不得不在蜂窝中调用 stopManagingCursor。
    • 嘿,也许是个愚蠢的问题,但VersionUtil 是什么?我无法导入它。
    • 这是我的内部类指定蜂窝版本public class VersionUtil { ... public static final int HONEYCOMB = 11; ... }
    【解决方案2】:

    我遇到了同样的问题,我想我可能已经找到了问题并进行了“干净”的修复。 (我认为完全停止管理游标不是一个好主意)

    我在一些活动中使用了 Adapter.changeCursor,这些活动在除蜂窝之外的所有版本中都运行良好。 changeCursor 方法关闭旧游标,但显然不会停止管理该游标。所以活动继续管理已经关闭的旧游标。在重新启动活动时,它会尝试重新查询它,而不检查它是否已关闭。

    所以我的解决方案是:

    Cursor oldCursor = mAdapter.getCursor();
    mAdapter.changeCursor(newCursor);
    stopManagingCursor(oldCursor);
    

    到目前为止,我无法再次重现异常。

    【讨论】:

    • 在 onPause 中,您在哪里执行此操作?也许你的问题和我的不同。我从来没有改变光标,但我仍然得到错误。
    • 我在(曾经)我更改光标的地方执行此操作。也许你的问题和我的不一样。
    【解决方案3】:

    这是 Honeycomb 中对游标管理方式所做的一些更改的效果。以前,如果您不止一次调用startManagingCursor,一切都继续正常工作,现在它将导致IllegalStateException,因为活动正在尝试重新查询已关闭的游标。解决方法是在再次调用startManagingCursor 之前关闭旧游标(就像交换游标时一样)。

    因此,您的 ParentActivity 是由于 Activity 内的托管游标生命周期而间接执行此操作。

    现在您提到您正在使用 ACL 和 CursorLoader,请确保在更改光标时调用 swapCursor(Cursor c),这应该可以解决您的问题。

    你可以在这里看到一些讨论:http://groups.google.com/group/android-developers/browse_thread/thread/658133bec901d7e

    【讨论】:

    • 我对您的回复感到有些困惑,因为我并没有真正交换任何游标,但我发现我仍在使用 startManagingCursor 并且我删除了这些行,现在一切都很开心。我非常感谢您抽出宝贵时间做出回应并为我指明正确的方向。非常感谢!!!
    • @Michael Little 没问题,我只是想覆盖我所有的基础,因为它们是解决相同问题的几种方法。很高兴我能帮上忙
    • 最好摆脱 startManagingCursor,在你的活动中创建 mCursor。在 onPause 或 onDestroy 中关闭它(取决于您是在 onResume 还是 onCreate 中填充它)。
    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2011-09-10
    相关资源
    最近更新 更多