我在后台线程(我用AsyncTask
)从互联网上下载了一些数据,下载时会显示进度对话框.方向更改,活动重新启动,然后我的AsyncTask完成-我想取消进度对话框并开始新的活动.但是调用disdissDialog有时会抛出异常(可能是因为活动已被销毁,而新活动尚未启动).
处理此类问题的最佳方法是什么(从后台线程更新UI,即使用户改变方向也能正常工作)?谷歌有人提供了一些"官方解决方案"吗?
我在后台线程(我用AsyncTask
)从互联网上下载了一些数据,下载时会显示进度对话框.方向更改,活动重新启动,然后我的AsyncTask完成-我想取消进度对话框并开始新的活动.但是调用disdissDialog有时会抛出异常(可能是因为活动已被销毁,而新活动尚未启动).
处理此类问题的最佳方法是什么(从后台线程更新UI,即使用户改变方向也能正常工作)?谷歌有人提供了一些"官方解决方案"吗?
第一步:让你的AsyncTask
成为一个static
嵌套类,或者一个完全独立的类,而不是一个内部(非静态嵌套)类.
步骤2:让AsyncTask
通过数据成员(通过构造函数和设置器设置)保持在Activity
上.
第3步:创建AsyncTask
时,将当前Activity
提供给构造函数.
第4步:在onRetainNonConfigurationInstance()
中,将AsyncTask
从原来的、现在要离开的活动中分离出来,然后将其返回.
第5步:在onCreate()
中,如果getLastNonConfigurationInstance()
不是null
,则将其投射到AsyncTask
班,并打电话给你的设定者,将你的新活动与任务联系起来.
第6步:不要引用doInBackground()
中的活动数据成员.
如果你遵循上面的食谱,一切都会奏效的.onProgressUpdate()
和onPostExecute()
在onRetainNonConfigurationInstance()
的开始和随后的onCreate()
的结束之间暂停.
Here is a sample project人演示这项技术.
另一种方法是抛弃AsyncTask
,把你的作品换成IntentService
.如果要完成的工作可能很长,并且无论用户在活动方面做了什么(例如下载一个大文件),都应该继续进行,这一点尤其有用.您可以使用有序广播Intent
让活动对正在完成的工作做出响应(如果它仍在前台),或者使用Notification
让用户知道工作是否已经完成.Here is a blog post,更多关于这个图案.