思考下面代码


如果没有仔细观察,上面的代码可能导致严重的内存泄露。android lint会给出下面的警告:
in android, handler classes should be static or leaks might occur.
但是到底是泄漏,如何发生的?让我们确定问题的根源,先写下我们所知道的
3、在java中,非静态的内部类和匿名类会隐式地持有一个他们外部类的引用。静态内部类则不会。
那么,到底是内存泄漏?好像很难懂,让我们以下面的代码作为一个例子


当这个activity被finished后,延时发送的消息会继续在主线程的消息队列中存活10分钟,直到他们被处理。这个消息持有这个activity的handler引用,这个handler有隐式地持有他的外部类(在这个例子中是sampleactivity)。直到消息被处理前,这个引用都不会被释放。因此activity不会被垃圾回收机制回收,泄露他所持有的应用程序资源。注意,第15行的匿名runnable类也一样。匿名类的非静态实例持有一个隐式的外部类引用,因此context将被泄露。
为了解决这个问题,handler的子类应该定义在一个新文件中或使用静态内部类。静态内部类不会隐式持有外部类的引用。所以不会导致它的activity泄露。如果你需要在handle内部调用外部activity的方法,那么让handler持有一个activity的弱引用(weakreference)以便你不会意外导致context泄露。为了解决我们实例化匿名runnable类可能导致的内存泄露,我们将用一个静态变量来引用他(因为匿名类的静态实例不会隐式持有他们外部类的引用)。


静态和非静态内部类的区别是比较难懂的,但每一个android开发人员都应该了解。开发中不能碰的雷区是什么?不在一个activity中使用非静态内部类, 以防它的生命周期比activity长。相反,尽量使用持有activity弱引用的静态内部类。
<a href="http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html" target="_blank">译文链接</a>
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载:http://www.cnblogs.com/kissazi2/p/4121852.html