Handler基本使用(一) new Handler

         通常我们使用如下方式获取一个Handler对象

 private Handler mHandler1 = new Handler(){
	    public void handleMessage(Message msg) {
	        
	    };
	};

	private Handler mHandler2 = new Handler(new Handler.Callback() {
        
        @Override
        public boolean handleMessage(Message msg) {
            return false;
        }
    });

        细心一点去看,使用第一种方式定义handler对象时,编译器会报如下警告:

       This Handler class should be static or leaks might occur             

        意思是,Handler类必须为静态的,否则有可能造成内存泄漏。

        这是为什么呢,事实上MessageQueen中等待处理的消息持有对Handler对象的引用,而上述第一种方式中我们的Hanler类是一个匿名内部类,它持有了所在外部类的引用(不只是匿名内部类,内部类也会引起这个问题)。一旦消息队列里的消息长时间未处理,那么handler对象就一直被持有,它的外部类也一直被持有,导致无法及时CG,内存泄漏就发生了。

        那为什么使用static修饰变量时,就可以避免内存泄漏呢?那是因为静态的方法和变量都不属于类本身,不会持有对类的引用,自然也不会出现内存泄漏了,但是这种方式又必须为静态的代码提供额外的内存,程序中大量使用handler时,这种处理到底合理不合理呢?

      经过网友的好心提示,特此更正及讲解第一二种方式的区别

      第一种方式new出的handler对象是一个匿名内部类,它直接持有外部类的引用,因此系统直接警告不要使用这种方式

      第二种方式new出的handler是一个对象,它本身不是匿名内部类,因此没有警告语句,这里需要提一句,它的回调函数确实也是一个匿名的内部类,但这并不表示handler是匿名内部类。当然第二种方式也是存在内存泄漏的风险的,所以想要直接避免类似的问题,我们可以继承handler 编写自己的实现类,详情可以参考篇末的文章。

     为什么这个检查语句只关注handler本身呢,下一篇文章里有讲到哦。

     匿名内部类的讲解百科就讲的很好,有疑问的朋友可以点开看看内部类

     另外,谢谢各位网友的提示和监督,人无完人,若有不对请多多指教,作者也会接纳意见,但是冷嘲热讽的也不说个所以然的就谢绝了,匿名内部类是什么都没搞清楚的请好好学习一下。

    关于警告语句的处理其实还有其他方法 可以参考点击打开链接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章