当异步任务在运行时处理屏幕方向变化

20

我已经被这个问题困扰了一段时间。当我有一个单独的Thread/AsyncTask运行时,如何正确处理屏幕方向的改变?目前,我的做法是

android:configChanges="orientation|keyboard|keyboardHidden"

在我的AndroidManifest.xml中使用configChanges,但这并不是鼓励的做法

注意:应尽量避免使用此属性,并仅在万不得已时使用。请阅读处理运行时更改以获取有关如何正确处理由于配置更改而导致的重启的更多信息。

此外,在2.3模拟器中,当切换到横屏时,它可以工作,但切换回竖屏会失败。

现在,我使用configChanges的原因是,当用户切换方向时,我可能正在运行一个AsyncTask,执行一些网络流量,并且我不希望它停止。

还有其他方法可以做到这一点吗?或者有没有办法修复2.3以切换回竖屏?

我知道onRetainNonConfigurationInstance,但我不确定“保存”AsyncTask实例是否是一个好主意,主要是因为扩展AsyncTask的类不是静态的(因此它与Activity相关联) - 它需要,因为在onPostExecute()中调用Activity实例的方法。

3个回答

7
我曾经遇到过类似的问题,通过实现继承自 Application 类的类来实现 AsyncTask。一个 Application 类在应用程序的整个生命周期内都可用,因此您不必担心除非整个应用程序被杀死,否则会中断您的 AsyncTask

要在任务完成时得到通知,Activity 必须实现一个接口,该接口用于向 Application 类注册自己。

当您的应用程序由于屏幕旋转而销毁时,您可以从 Application 类注销您的 Activity 并在重新创建时重新注册它。如果任务在销毁和重新创建之间完成,则操作的结果可以同时存储在 Application 类中,以便 Activity 在重新创建时可以检查任务是否仍在运行或结果是否已经可用。

另一个优点是,由于 Application 类是 Context 类的子类,因此您可以直接访问应用程序上下文。


非常好,比实现一个“服务”要简单得多。谢谢。 - Felix
@Flo 我知道这篇文章已经过去一段时间了,但我正在尝试做同样的事情,但我不太明白你的“要在任务完成时得到通知,Activity 必须实现一个接口,并使用它向 Application 类注册自己”的意思。能否给个例子?(我是 Java 和 Android 方面的新手) - Bex
抱歉,我没有代码示例。但是请看一下观察者模式,希望你能理解我所说的“注册”(update())和“通知”(addObserver())。 - Flo
2
啊,在我之前的评论中,我搞混了一些东西。 "注册" 意味着调用 addObserver() 方法,而 "通知" 意味着调用 update() 方法。 - Flo


0

我已经在这里提出了类似的问题。

基本上有一个示例,展示如何在设备旋转时暂停/恢复AsynTask。然而,它仍然不适用于所有情况(有时无法安全地暂停操作,例如在远程服务器上创建新用户)。对于这些“不安全”的情况,您需要编写一些我称之为棘手的“框架”代码。您将看到CommonsWare给出了其中一个的github链接。


所以没有简单的方法可以在“Activity”重新启动时保持“AsyncTask”运行。遗憾。但是,我发现不切换回纵向是模拟器问题,因为设置应用程序也会出现相同的情况。 - Felix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接