【发布时间】:2011-02-16 13:43:08
【问题描述】:
当我的 Activity 完成时,将 Activity 上下文的引用设为 null 是一种好习惯吗?我有 3 个 AsyncTask,每个都可以同时在多个实例中运行。在 onPostExecute() 中更新 UI。在 onDestroy() 中清空所有 Activity Context 引用将非常困难,并且会使代码变得混乱。最好的办法是什么?
【问题讨论】:
当我的 Activity 完成时,将 Activity 上下文的引用设为 null 是一种好习惯吗?我有 3 个 AsyncTask,每个都可以同时在多个实例中运行。在 onPostExecute() 中更新 UI。在 onDestroy() 中清空所有 Activity Context 引用将非常困难,并且会使代码变得混乱。最好的办法是什么?
【问题讨论】:
查看WeakAsyncTask 来自 Google 的示例,该示例说明在活动生命周期之外不会保持引用保持活动状态,以及来自 DroidFu 的BetterAsyncTask 示例,说明连接 AsyncTask 以便它们可以重新连接到新活动实例的方法示例(例如,在旋转之后);用法示例为here。
将 Activity 的引用保留在一个简短的操作(例如单个小 Web 请求或小文件写入)可能没有太大的危害,但如果任务有可能堆积起来,则可能会导致问题.例如,如果您的应用在创建时从服务器读取一个 200KB 的 XML 文件,比方说这可能需要 1 分钟或更长时间超过 EDGE,那么快速打开/关闭手机 3 或 4 次可能会导致 4 个保留的 Activity 实例 - - 在这种情况下你会很快耗尽内存,更不用说重复的工作了。
但是,对于任何真正长时间运行的进程,您绝对应该考虑使用IntentService 而不是 AsyncTask。它们专为与特定活动无关的长期运行流程而设计 - 例如您如何发送彩信并离开活动去做其他事情,并且您会得到一个愉快的祝酒词,通知您完成任务完成。
【讨论】:
不要保留对上下文活动的长期引用(对活动的引用应该与活动本身具有相同的生命周期)。尝试使用上下文应用程序而不是上下文活动。当你因为内存问题不需要相反时,不需要清空引用。
【讨论】:
如果在您的 Activity 完成后不久这些任务本身就有资格进行垃圾收集,我认为保留引用没有问题。
如果任务确实比活动存活了很长时间,则应将所有对活动上下文的引用设置为空。另见文章Avoiding Memory Leaks。
无论哪种方式,最好尽可能使用应用程序上下文 (getApplicationContext()) 而不是活动上下文。在这种情况下你不能这样做,因为你需要发布 UI 消息;我只是为了完整性而提及它。
【讨论】:
您可以使用弱引用来保持上下文引用。 http://developer.android.com/reference/java/lang/ref/WeakReference.html
弱引用对象可以被 GC'd。您应该在每次使用时检查上下文引用是否仍然有效。
【讨论】: