new Handler().postDelayed(new Runnable(){
@Override
public void run() {
// do stuff
}}, 100);
如果我从一个activity(onCreate或onResume或别的地方)调用这个会导致内存泄漏吗?我读过new Runnable()
实际上应该是一个静态实例,这是真的吗?匿名处理程序或Runnable会造成内存泄漏吗?
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
// do stuff
}}, 100);
如果我从一个activity(onCreate或onResume或别的地方)调用这个会导致内存泄漏吗?我读过new Runnable()
实际上应该是一个静态实例,这是真的吗?匿名处理程序或Runnable会造成内存泄漏吗?
是的。此代码可能会导致内存泄漏。
只要基于Runnable
的匿名类在队列中(本例中为100毫秒),它就会保留对外部Activity
类的引用。
这样的内存泄漏当然不是一个问题,但根据执行的内部代码run
,它可能会产生更大的问题,例如在您遇到问题时崩溃应用程序。在Activity
死亡后尝试显示对话框。在这种情况下,你会看到漂亮的信息例外:
抛出:IllegalArgumentException:的onSaveInstanceState后
或
BadTokenException无法执行此操作:无法添加窗口 - ...是你的活动运行?
是的,这是一个泄漏。由于处理程序的工作方式,它们可以长时间保持活力,并防止他们参考的任何资源被垃圾收集。这里是一个很好explantion:http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html
如果您运行的可能活得比你的对象的生命周期,而不是尝试在回答这里的做法:https://stackoverflow.com/a/27825703/579234
你在做什么是添加对象的另一个层次上的顶部这将引发对非静态处理器类的现有皮棉警告通常情况下会触发皮棉警告:Android lint checks:
HandlerLeak ----------- Summary: Ensures that Handler classes do not hold on to a reference to an outer class Priority: 4/10 Severity: Warning Category: Performance In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread's MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.
使用匿名类是在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)。
因此,为了明确解释,您的runnable持有对'this'的引用,并且处理程序持有对runnable的引用,因此'this'不会被垃圾收集,直到处理程序死亡。
你已经读过它应该是一个静态*类。*匿名类不能是静态的,但是你不应该以这种方式使用它。但问题在于非静态性,而不是匿名性。 – EJP