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本身呢,下一篇文章裏有講到哦。

     匿名內部類的講解百科就講的很好,有疑問的朋友可以點開看看內部類

     另外,謝謝各位網友的提示和監督,人無完人,若有不對請多多指教,作者也會接納意見,但是冷嘲熱諷的也不說個所以然的就謝絕了,匿名內部類是什麼都沒搞清楚的請好好學習一下。

    關於警告語句的處理其實還有其他方法 可以參考點擊打開鏈接

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