下面的文档页面提到android可能会在某些情况下销毁一个活动实例,并在之后以其先前保存的状态重新创建它。
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
我想知道如果活动被销毁并重新创建,下面两种情况会发生什么。
1)活动有一个匿名AsyncTask
正在运行,它在完成时为UI元素设置了一些值。如果在AsyncTask
仍在运行时活动被销毁,那么AsyncTask
完成后会发生什么?如果在onPostExecute()
上访问了某些UI元素,是否会导致异常?如果没有,重新创建活动时,onPostExecute()
中的更改是否可见?
2)如果使用View.setTag()将某个对象设置为View
元素中的标记,则在销毁并重新创建活动后,设置为标记的对象是否仍然可用于重新创建查看?
答案 0 :(得分:1)
1)如果您尝试从旧的Activity对象访问UI元素,它将引发异常。在内部,创建了一个全新的Activity对象以及新的View对象,这意味着旧的引用将无效。请记住,如果您持有硬参考,则会使用AsyncTask泄漏内存。
2)这里发生了同样的事情。将创建一个新的View对象,旧View的所有成员变量都将丢失。
只有onSaveInstanceState()
方法中保存的数据才会结转。您可以通过在手机的开发人员选项中启用“不要保持活动”,甚至更改方向来轻松测试此方案。您还可以使用调试器验证是否创建了新的对象引用。
答案 1 :(得分:1)
要添加其他人的评论,如果你要运行AsyncTask,你应该在onPostExecute方法中做的第一件事就是检查活动状态:
if (!isFinishing()) { ... }
碎片具有类似的逻辑
if (isAdded() && !getActivity().isFinishing()) { ... }
就个人而言,我更喜欢将RxJava与RxLifecyle扩展一起使用,因为它使处理起来更加清晰,但这是另一天的故事。
答案 2 :(得分:0)
当Async Task完成时,AsyncTask不会更新新Activity的UI。实际上,它将尝试更新实际上不存在的活动的前一个实例。所以这可能会导致异常IllegalArgumentException或illegalStateException
为什么不尝试只创建1000次迭代循环的异步任务并按回去销毁活动并查看结果