Handler用于处理和从队列MessageQueue中得到Message。1般我们要重写Handler的handleMessage(Message msg){}方法来处理,以下代码:
这个时候Handler会被Android SDK中Lint工具检查正告你(左侧那个黄色灯泡+叹号):This Handler class should be static or leaks might occur 。
This Handler class should be static:
(知识点1)为何静态内部类可以解决这个问题呢?或说静态内部类和非静态内部类的区分是甚么?
举例:class A{int a; static int b class B{} static class C{} } (A是外部类,B非静态内部类,C静态内部类,a普通字段,b静态字段)
1)B非静态内部类:
可以访问A.a和A.b,也就是外部的属性都能方位。由于B隐式的持有A类对象的援用,相当于A的属性
2)C静态内部类:
C只可以访问A.b,不可以方位A.a。为何?由于C不含有A的援用,它和A类是同1个级别,只不过写到了A类的内部。
本例缘由:
Handler匿名内部类,隐式的持有了外部类Activity的援用(这就是为何你能在handleMessage()中调用MainActivity中TextView等的属性)。--->而以后调
在100秒后message被履行,这期间message被放在MessageQueue中,MessageQueue在Looper中,Looper是线程的本地变量。
也就是说MainActivity即便生命周期走完了也不会垃圾回收,为何?由于Java的垃圾回收机制,就是看1个对象有无被援用(从线程中的主要对象开始,对象之间的援用构成网状结构,如果有类的对象不在这张网上,就证明它没被援用。这就是数据结构中图的遍历,甚么连通子图,非连通子图)。而本文中1个MainActivity被Handler持有援用,Handler被Message持有援用,Message被MessageQueue持有援用,MessageQueue被Looper持有援用,Looper为线程本地变量,线程不被摧毁,它就不会被烧毁。
所以即使用户已切换、退出到别的Activity,MainActivity占有的内存仍旧不会被释放。
打破援用链:
1.Message在100秒后被处理,以后回收Message,然后回收MainActivity。(所以是实际上,你只要不发很长时间的Message也不会有甚么问题)
2.使Handler不持有MainActivity的援用,用弱援用WeakReference:(简单讲,就是只有WeakReference援用的对象,垃圾回收将回收该对象,以后再另写1篇援用的文章吧)