我下载了一些数据从互联网在后台线程(我使用AsyncTask)和显示进度对话框,而下载。方向改变,活动重新启动,然后我的AsyncTask完成-我想解散进程对话框,并启动一个新的活动。但是调用disdisdialog有时会抛出一个异常(可能是因为Activity已经被销毁并且新的Activity还没有启动)。

处理这类问题的最佳方法是什么(从后台线程更新UI,即使用户改变方向也能工作)?谷歌是否有人提供了一些“官方解决方案”?


当前回答

4年后,谷歌解决了问题,只是在onCreate活动中调用setRetainInstance(true)。它将在设备旋转期间保存您的活动实例。对于旧版本的Android,我也有一个简单的解决方案。

其他回答

您应该使用活动处理程序调用所有活动操作。因此,如果你在某个线程中,你应该创建一个Runnable,并使用活动的处理程序发布。否则你的应用程序有时会崩溃,出现致命异常。

谷歌是否有人提供了一些“官方解决方案”?

Yes.

解决方案更像是一个应用程序体系结构建议,而不仅仅是一些代码。

他们提出了3种设计模式,允许应用程序与服务器同步工作,无论应用程序状态如何(即使用户完成应用程序,用户更换屏幕,应用程序被终止,任何其他可能的状态,后台数据操作可能被中断,它也会工作,这包括在内)

Virgil Dobjanschi在谷歌I/O 2010期间的Android REST客户端应用程序演讲中解释了这个提议。它只有1小时长,但非常值得一看。

它的基础是将网络操作抽象为独立于应用程序中的任何活动的服务。如果您正在使用数据库,使用ContentResolver和Cursor将为您提供一个开箱即用的Observer模式,一旦您使用获取的远程数据更新了本地数据库,就可以方便地更新UI,而无需任何额外的逻辑。任何其他后续操作代码都将通过传递给服务的回调运行(为此我使用ResultReceiver子类)。

不管怎样,我的解释其实很模糊,你一定要看这个演讲。

已接受的答案非常有用,但它没有进度对话框。

读者,幸运的是,我已经创建了一个非常全面和工作的AsyncTask示例,其中包含一个进度对话框!

旋转工作,对话框保存下来。 您可以通过按后退按钮取消任务和对话框(如果您想要这种行为)。 它使用片段。 当设备旋转时,活动下面的片段的布局会适当地改变。

4年后,谷歌解决了问题,只是在onCreate活动中调用setRetainInstance(true)。它将在设备旋转期间保存您的活动实例。对于旧版本的Android,我也有一个简单的解决方案。

这是我的解决方案:https://github.com/Gotchamoh/Android-AsyncTask-ProgressDialog

基本步骤如下:

我使用onSaveInstanceState保存任务,如果它仍然 处理。 在onCreate我得到的任务,如果它被保存。 在onPause我放弃ProgressDialog如果它是显示。 在onResume中,如果任务仍然,我将显示ProgressDialog 处理。