在onDestroy中释放资源真的是错误的行为吗?

4

Android文档中提到(在http://developer.android.com/training/basics/activity-lifecycle/stopping.html):

在极端情况下,系统可能会直接杀死您的应用程序进程而不调用活动的最终onDestroy()回调,因此使用onStop()释放可能会泄漏内存的资源非常重要。

听起来好像是错误的。被杀死的进程怎么可能会泄漏内存?


主进程会被杀死,但并非所有请求的资源都会被杀死。 - kabuto178
1个回答

8
假设您在onStart()方法中启动了一个服务,并且打算在用户退出Activity时停止该服务。
如果您将停止服务的代码放在onDestroy()中,那么该代码可能永远不会被调用,这可能会导致该服务一直运行,直到Android决定终止它(这可能要等很长时间,甚至永远不会发生)。这运行中的服务是泄露内存/资源到应用程序外的示例。
您应该将类似于那样的清理代码放在保证被调用的方法中。
请注意,进程在调用onPause()后可以被杀死,因此onPause()是您想要进行绝对必须进行清理的地方。
(有关Activity生命周期的详细信息,请参见https://developer.android.com/guide/components/activities.html中的表1)
可能泄漏的另一件非常糟糕的事情:蓝牙发现或位置报告(GPS或基于网络)打开但没有尽快关闭-这对电池寿命非常不利。

我应该指出,蓝牙发现会超时,但它非常耗电,您应该在不再需要它时立即关闭它。(超时时间可以长达300秒) - Scott Stanchfield
1
如果进程被杀掉,它的 VM 也会被杀掉,并且所有内存都被返还给操作系统,那么为什么 Activity 不会被释放出来? - user983447
@user983447 - 很好的观点 - 我已经删除了那个引用。我没有考虑到管理器实例在同一个进程中的情况。如果进程没有被杀死,开发人员没有取消注册传感器监听器,这将是更大的问题。 - Scott Stanchfield
我刚刚检查了一下 - 当活动请求位置更新,然后从未删除更新并被杀死时,GPS会被Android停止。因此,似乎在onDestroy中执行removeUpdates并没有什么不好的 - 即使在进程被杀死时没有调用onDestroy,Android也会关闭GPS。 - user983447
另一个(更重要的)需要考虑的事情是,在调用startActivity()移动到下一个活动时,是否希望GPS更新(或其他已启动的操作)继续。在这种情况下,该活动可能会保持“停止”状态;onDestroy()没有被调用。很可能在您的第二个活动中不需要原始GPS监听器。即使不需要,它也会在第二个活动期间挂起。 - Scott Stanchfield

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