Android: 屏幕旋转时如何移除/销毁对象

3
我发现在屏幕旋转一次或多次后性能会下降,我认为这可能是因为每次屏幕旋转时应用程序的主Activity都会被销毁并重新创建,而我的应用程序在此过程中可能存在内存泄漏。
我了解到,与人们预期的不同,应用程序的主Activity(或由该Activity调用的类)创建的并非所有对象都会在Activity被销毁时被销毁。具体来说,如果视图使用一个大的位图成员对象,则应重写Activity的onDestroy()方法并显式回收位图,尽管我现在找不到相关阅读材料了。
还有其他需要在Activity被销毁时销毁或移除的对象吗?监听器呢?是否有全面的教程或指南涵盖了这个主题?
2个回答

5

有没有关于这个主题的全面教程或指南?

实际上没有。

在Activity被销毁时,是否还有其他需要销毁或删除的对象?监听器呢?

位图比较特殊,部分原因是它们使用16MB堆之外的内存,如果我正确理解了Android复杂的内存模型的话。

除了大型位图之外,你真正需要担心的最大问题是阻止正常垃圾回收工作的事物。任何直接或间接地持有Activity的静态上下文的东西都会阻止Activity被垃圾回收。例如:

  • 类上的静态数据成员(例如,你用自己的服务之一来构建自己的监听器框架,所以你的服务持有一个监听器,该监听器又持有你的Activity)
  • 线程(例如,你手动分离一个后台线程并且没有终止它)

感谢您的及时回答。由于我不知道如何创建自己的服务或分叉线程,我认为这些都不是我的问题。有一件事我不明白,根据基本原则,当对象超出范围时,GC会从中回收内存,为什么在Activity结束时创建的位图不会发生这种情况。我觉得如果我理解了这一点,我就有更好的机会识别可能导致类似问题的其他事情。 - prepbgg
首先,我不理解的一件事是,鉴于垃圾回收机制的基本原则是在对象离开作用域时收回内存,为什么在 Activity 结束时创建的位图并没有被回收。其次,GC 不是立即执行的。它是异步进行的。对于像位图这样的大内存块,可能会太晚了,因此有一种机制可以向 Android 主动提示可以回收位图(例如供下一个 Activity 使用)。 - CommonsWare
我还有一个大位图,它被定义并用作我的一个类的方法中的局部变量。我一直认为,由于它纯粹是在本地使用,所以没有必要回收它。然而,考虑到你对GC如何工作的解释,我现在想知道是否也需要回收这个位图? - prepbgg
大型位图需要比大多数本地变量更加小心。我会尝试主动回收它,而不仅仅依赖垃圾回收。 - CommonsWare
好的。我现在已经添加了代码来回收“临时”位图。如果DDMS中的SysInfo图包括位图和堆,这个更改似乎已经减少了内存需求,尽管每次屏幕旋转仍然存在一个小的泄漏问题,我必须进行调查。 - prepbgg

1
请注意,在清单文件中添加 android:configChanges="orientation" 可以防止屏幕旋转时 Activity 被销毁。因此,我不再需要担心是否需要销毁或删除单个位图或其他对象了!(感谢 Ribo 在另一个线程中指出这一点。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接