new Handler().postDelayed(new Runnable(){
@Override
public void run() {
// do stuff
}}, 100);
如果我从活动(onCreate 或 onResume 或其他地方)调用它,这会导致内存泄漏吗?我读过new Runnable()
实际上应该是一个静态实例,是这样吗?
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
// do stuff
}}, 100);
如果我从活动(onCreate 或 onResume 或其他地方)调用它,这会导致内存泄漏吗?我读过new Runnable()
实际上应该是一个静态实例,是这样吗?
是的。此代码可能会导致内存泄漏。
只要这个基于的匿名类Runnable
在队列中(本例中为 100 毫秒),它就会保持对外部Activity
类的引用。
这样的内存泄漏本身当然不是问题,但是根据run
执行内部代码的不同,它可能会产生更大的问题,例如当您尝试在Activity
被杀死后显示对话框时使应用程序崩溃。在这种情况下,您会看到很好的信息异常:
IllegalArgumentException:onSaveInstanceState 后无法执行此操作
或者
BadTokenException:无法添加窗口 - ...您的活动正在运行吗?
是的,这是一个泄漏。由于 Handlers 的工作方式,它们有可能在很长一段时间内保持活动状态,并防止它们引用的任何资源被垃圾收集。这是一个很好的解释:http ://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html
如果您的可运行文件可能超过对象的生命周期,请尝试此处的答案中的方法:https ://stackoverflow.com/a/27825703/579234
您正在做的是在通常情况下添加另一个级别的对象,这将触发现有的关于非静态处理程序类的 Lint 警告将触发 Lint 警告:Android lint checks:
处理程序泄漏 ------------ 摘要:确保 Handler 类不持有对 外层 优先级:4 / 10 严重性:警告 类别:性能 在 Android 中,处理程序类应该是静态的,否则可能会发生泄漏。留言 在应用程序线程的 MessageQueue 上排队也保留了它们的目标 处理程序。如果 Handler 是一个内部类,它的外部类将被保留为 出色地。为避免泄漏外部类,请将 Handler 声明为静态嵌套 具有对其外部类的 WeakReference 的类。
使用匿名类与http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5中所述相同:
匿名类始终是内部类(第 8.1.3 节);它永远不是静态的(§8.1.1、§8.5.1)。
因此,为了明确解释,您的可运行对象包含对“this”的引用,而处理程序持有对可运行对象的引用,因此在处理程序死亡之前不会对“this”进行垃圾收集。