Activity中Handler使用的正確姿勢,避免內存泄漏

原博客地址:https://blog.csdn.net/weixin_40400031/article/details/96324854


 

使用Handler來解決通訊問題,是開發必備技能,但就是這家喻戶曉的Handler,卻偏偏最容易造成內存泄漏。

接下來我列出幾種使用Handler的方式,以及各自的問題:

 

關於內存泄漏,請參考:Android 關於內存泄露,你必須瞭解的東西

關於JAVA引用類型,請參考:你真的懂 Java 的內存管理和引用類型嗎?

 

第一種(公開靜態handler):

寫法:在Activiy中創建公開靜態handler (public static Handler  handler),並在onCreate()中實例化,以給其他類使用。

優點:這樣創建handler,可以隨意實現Activity與Activity/Service進行通訊,只要在需要的地方,使用目的Activity的handler調用sendMessage()即可。

缺點:必會造成內存泄漏  (因爲static變量本身不持有Activity的引用,但是在onCreate()中實例化就給handler加上了對Activity的強引用。當Activity銷燬的時候,由於handler的強引用,導致Activity無法被GC回收)

解決辦法:無藥可救,被static變量持有了強引用,那就完了

 

第二種(非靜態handler):

寫法:在Activity創建一個非靜態匿名內部類對象handler  (private Handler handler ) ,並在onCreate()中實例化

優點:相比於第一種,非靜態handler不能被其他類隨意使用,但依舊可以用於網絡等耗時操作,用作結束時的通知(在調用耗時操作時將handler作爲參數傳遞過去,之後等耗時操作結束,再使用該handler調用sendMessage()即可)。但是不會像第一種那樣百分百造成內存泄漏。

缺點:1.只有Activity主動給予handler的地方纔可以使用,無法實現Activity與Activity之間的通訊。

           2.如果Activity銷燬時,Handler有未處理或處理中的Message,則Message持有handler,handler持有Activity,導致Activity無法回收

解決辦法:在Activity的onDestroy()中調用handler.removeCallbacksAndMessages()切斷Handler與Activity之間的引用。

 

第三種(自定義Handler,內部對Activity進行弱引用)

寫法:

//創建子類,採用弱引用:
public abstract class MyHandler extends Handler  {
    private Activity activity ;
    private WeakReference<Activity> weakReference ;

    public MyHandler(Activity activity) {
        weakReference = new WeakReference<Activity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);

        if(weakReference.get() == null){
            return;
        }else{
            handle(msg); //處理message
        }
    }
    
    public abstract void handle(Message msg);
}
//在Activit中創建實例
public class HandlerActivity extends BaseActivity {
    public  MyHandler handler ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);

        handler = new MyHandler(context){
            @Override
            public void handle(Message msg) {
                //do something...
            }
        };
    }
}

優點:由於使用了弱引用(WeakReference),所以Activity銷燬時,即使Handler還有message要處理,Activity也依舊會被GC回收。其他功能同第二種。

缺點:沒啥缺點,就是要單獨寫個子類

 

最後:大家不要搞這麼蛋疼的Handler了,在通訊這塊還是使用EventBus這類成熟框架吧!

如果嫌EventBus書寫分類繁瑣,可以參考小弟的框架EventBox

 

以上若有不對的,還望指教,謝謝

 

 

 

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