如何使我的光标在方向改变后仍能幸存?

发布于 2024-10-13 13:10:09 字数 1813 浏览 6 评论 0原文

我试图使我的应用程序旋转友好,但在保存光标时遇到一些问题。

游标保存了 ListView 中显示的大约 13k+ 行数据,因此如果我每次配置更改时都进行重新查询,将需要相当长的时间。在我的 onRetainNonConfigurationInstance() 中,我返回我的 Cursor,然后通过 getLastNonConfigurationInstance() 检索它。

但是,我检索到的光标似乎已经关闭,因此我的适配器无法再呈现列表。据我了解,游标已关闭,因为 onDestroy() 自动关闭所有游标。

我像这样保存光标:

@Override
public Object onRetainNonConfigurationInstance() {
    return myCursor;
}

并像这样检索它:

myCursor = (Cursor)getLastNonConfigurationInstance();
if (myCursor == null) {
    // Do some stuff here (access DB, etc)
} else { // we are returning from configuration change
    // Feed the cursor to the adapter
}

如果有人想查看它,我将粘贴堆栈跟踪:

01-25 16:57:45.637: ERROR/AndroidRuntime(12976): android.database.StaleDataException: Access closed cursor
    01-25 16:57:45.637: ERROR/AndroidRuntime(12976):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:217)
    01-25 16:57:45.637: ERROR/AndroidRuntime(12976):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
    01-25 16:57:45.637: ERROR/AndroidRuntime(12976):     at com.test.sample.helper.DictionaryAdapter.bindView(DictionaryAdapter.java:35)
[........More ListView-related errors here..........]

我单步执行代码,发现只要 onRetainNonConfigurationInstance() ,游标仍然打开,但通过 getLastNonConfigurationInstance() 获取后它已经关闭。

如何使我的光标在方向变化中幸存下来?谢谢您的帮助!

编辑: 根据Romain的回答,我注释掉了所有的startManagingCursor()。我应该把这些点联系起来并思考一下!无论如何,我的应用程序现在可以在一次旋转中幸存下来,但将其翻转回原始方向仍然会崩溃。继续我的调试,会让你知道我发现了什么。

编辑2: 我想我可能已经找到了导致新错误的原因。我已经实现了一个返回新游标的FilterQueryProvider。我所做的就是将该过滤器的结果分配给我原来的光标。到目前为止似乎有效。

I am trying to make my app rotation friendly, but I am having some problems saving the cursor.

The cursor holds about 13k+ rows of data displayed in a ListView, and thus would take quite a while if I would do a requery every time the configuration changes. In my onRetainNonConfigurationInstance(), I am returning my Cursor and then retrieving it through getLastNonConfigurationInstance().

However, my retrieved cursor seems to be closed already, and thus my adapter cannot render the list anymore. From what I understand, the cursor was closed since onDestroy() automatically closes all cursors.

I save the Cursor like this:

@Override
public Object onRetainNonConfigurationInstance() {
    return myCursor;
}

And retrieve it like this:

myCursor = (Cursor)getLastNonConfigurationInstance();
if (myCursor == null) {
    // Do some stuff here (access DB, etc)
} else { // we are returning from configuration change
    // Feed the cursor to the adapter
}

I am pasting the stack trace if someone wants to look at it:

01-25 16:57:45.637: ERROR/AndroidRuntime(12976): android.database.StaleDataException: Access closed cursor
    01-25 16:57:45.637: ERROR/AndroidRuntime(12976):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:217)
    01-25 16:57:45.637: ERROR/AndroidRuntime(12976):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
    01-25 16:57:45.637: ERROR/AndroidRuntime(12976):     at com.test.sample.helper.DictionaryAdapter.bindView(DictionaryAdapter.java:35)
[........More ListView-related errors here..........]

I stepped through the code and I found out that as far as onRetainNonConfigurationInstance(), the cursor is still open, but after getting it through getLastNonConfigurationInstance() it is already closed.

How can I make my Cursor survive the orientation change? Thank you for the help!

EDIT:
Based on Romain's answer, I commented out all my startManagingCursor()s. I should have connected the dots and thought about it! Anyway, my app now survives one rotation, but flipping it back to the original orientation still crashes it. Continuing my debugging and will let you know what I find out.

EDIT2:
I think I may have found what is causing the new errors. I have implemented a FilterQueryProvider which returns a new Cursor. What I did was assign the results of that filter to my original Cursor. Seems to work so far.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自在安然 2024-10-20 13:10:10

您可能正在使用托管游标。当活动被销毁时,托管游标会自动关闭。您应该切换到非托管游标。

You are probably using a managed cursor. Managed cursors are automatically closed when the Activity is destroyed. You should switch to an unmanaged Cursor.

似梦非梦 2024-10-20 13:10:10

只需在清单文件的活动标记中添加此属性

android:configChanges="orientation|keyboardHidden"

即可解决此问题,

无需实现其他任何内容

:)
不过它对我有帮助

Just add this attribute in your activity tag in the manifest file

android:configChanges="orientation|keyboardHidden"

it will resolve this

no need to implement anything else

:)
It helped me though

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文