后台任务、进度对话框、方向改变 - 有没有 100% 有效的解决方案? [英] Background task, progress dialog, orientation change - is there any 100% working solution?

查看:15
本文介绍了后台任务、进度对话框、方向改变 - 有没有 100% 有效的解决方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在后台线程中从 Internet 下载了一些数据(我使用 AsyncTask)并在下载时显示进度对话框.方向改变,活动重新启动,然后我的 AsyncTask 完成 - 我想关闭进程对话框并启动一个新的活动.但是调用dismissDialog有时会抛出异常(可能是因为Activity被销毁了,新的Activity还没有启动).

I download some data from internet in background thread (I use AsyncTask) and display a progress dialog while downloading. Orientation changes, Activity is restarted and then my AsyncTask is completed - I want to dismiss the progess dialog and start a new Activity. But calling dismissDialog sometimes throws an exception (probably because the Activity was destroyed and new Activity hasn't been started yet).

处理此类问题的最佳方法是什么(即使用户更改方向也能从后台线程更新 UI)?Google 是否有人提供了一些官方解决方案"?

What is the best way to handle this kind of problem (updating UI from background thread that works even if user changes orientation)? Did someone from Google provide some "official solution"?

推荐答案

第 1 步:使您的 AsyncTask 成为一个 static 嵌套类,或者一个完全独立的类,只需不是内部(非静态嵌套)类.

Step #1: Make your AsyncTask a static nested class, or an entirely separate class, just not an inner (non-static nested) class.

第 2 步:让 AsyncTask 通过数据成员保持 Activity,通过构造函数和 setter 设置.

Step #2: Have the AsyncTask hold onto the Activity via a data member, set via the constructor and a setter.

第 3 步:创建 AsyncTask 时,将当前的 Activity 提供给构造函数.

Step #3: When creating the AsyncTask, supply the current Activity to the constructor.

第 4 步:在 onRetainNonConfigurationInstance() 中,返回 AsyncTask,将它从原始的、现在离开的活动中分离出来.

Step #4: In onRetainNonConfigurationInstance(), return the AsyncTask, after detaching it from the original, now-going-away activity.

第 5 步:在 onCreate() 中,如果 getLastNonConfigurationInstance() 不是 null,则将其转换为您的 AsyncTask 类并调用您的 setter 将您的新活动与任务相关联.

Step #5: In onCreate(), if getLastNonConfigurationInstance() is not null, cast it to your AsyncTask class and call your setter to associate your new activity with the task.

第 6 步:不要从 doInBackground() 中引用活动数据成员.

Step #6: Do not refer to the activity data member from doInBackground().

如果你按照上面的方法,一切都会奏效的.onProgressUpdate()onPostExecute()onRetainNonConfigurationInstance() 的开始和后续 onCreate()<的结束之间暂停/代码>.

If you follow the above recipe, it will all work. onProgressUpdate() and onPostExecute() are suspended between the start of onRetainNonConfigurationInstance() and the end of the subsequent onCreate().

这是一个演示该技术的示例项目.

另一种方法是抛弃 AsyncTask 并将您的工作转移到 IntentService 中.如果要完成的工作可能很长并且无论用户在活动方面做什么(例如,下载大文件)都应该继续进行,这将特别有用.您可以使用有序广播 Intent 来让 Activity 响应正在完成的工作(如果它仍在前台)或引发 Notification 以让用户知道如果工作已经完成.这是一篇博文,内容更多模式.

Another approach is to ditch the AsyncTask and move your work into an IntentService. This is particularly useful if the work to be done may be long and should go on regardless of what the user does in terms of activities (e.g., downloading a large file). You can use an ordered broadcast Intent to either have the activity respond to the work being done (if it is still in the foreground) or raise a Notification to let the user know if the work has been done. Here is a blog post with more on this pattern.

这篇关于后台任务、进度对话框、方向改变 - 有没有 100% 有效的解决方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆