您好,登錄后才能下訂單哦!
這篇文章給大家介紹在Android應(yīng)用中使用Handler時出現(xiàn) leak如何解決,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
在Android中,Handler類應(yīng)該是靜態(tài)的,否則,可能發(fā)生泄漏。在應(yīng)用程序線程的MessageQueue中排隊的Message對象 還保留他們的目標(biāo)Handler。如果Handler是一個內(nèi)部類(注:無論是匿名還是非匿名,匿名是比較常見用法),它的外部類將被保留(至于為什么, 請參考Java嵌套類相關(guān)說明)。為了避免泄漏外部類,聲明一個Handler子類為靜態(tài)內(nèi)部類(注:這樣就避免了Handler對象對外部類實例的自動引用),其內(nèi)部持有一個對外部類對象的WeakReference。
上面是HandlerLeak的詳細(xì)解釋,同時下劃線部分也提供了解決方案的思路。我們需要再分析一下幾個泄漏問題:(1) 排隊中的Message對象對Handler的持有導(dǎo)致泄漏;(2)Handler對象對外部類(如Activity或Service)實例的強引用持 有。是由于這兩個原因同時作用導(dǎo)致出現(xiàn)泄漏的可能。我們的解決方案可以從原因出發(fā),清除這兩個原因,就會比較完整的解決這個問題。
方案:(1)針對第1個原因,在使用Handler的組件生命周期結(jié)束前清除掉MessageQueue中的發(fā)送給Handler的Message對象(例如在Activity或Service的onDestroy()中調(diào)用Handler的remove*方法);(2)針對第2個原因,Handler的實現(xiàn)類采用靜態(tài)內(nèi)部類的方式,避免對外部類的強引用,在其內(nèi)部聲明一個WeakReference引用到外部類的實例。
關(guān)于Handler的remove*方法,這兒介紹一下(可以參考源碼或文檔)
removeCallbacks(Runnable r) ——清除r匹配上的Message。
removeCallbacks(Runnable r, Object token) ——清除r匹配且匹配token(Message.obj)的Message,token為空時,只匹配r。
removeCallbacksAndMessages(Object token) ——清除token匹配上的Message。
removeMessages(int what) ——按what來匹配
removeMessages(int what, Object object) ——按what來匹配
我們更多需要的是清除以該Handler為target的所有Message(包括Callback),那么調(diào)用如下方法即可
handler.removeCallbacksAndMessages(null);
最終代碼像下面這樣
package org.dragonboy.example; import java.lang.ref.WeakReference; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; /** * @author dragonboyorg@qq.com */ public class MyActivity extends Activity { private MyHandler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mHandler = new MyHandler(this); } @Override protected void onDestroy() { // Remove all Runnable and Message. mHandler.removeCallbacksAndMessages(null); super.onDestroy(); } static class MyHandler extends Handler { // WeakReference to the outer class's instance. private WeakReference<myactivity> mOuter; public MyHandler(MyActivity activity) { mOuter = new WeakReference<myactivity>(activity); } @Override public void handleMessage(Message msg) { MyActivity outer = mOuter.get(); if (outer != null) { // Do something with outer as your wish. } } } } </myactivity></myactivity>
關(guān)于在Android應(yīng)用中使用Handler時出現(xiàn) leak如何解決就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。