1. 程式人生 > >Android效能優化之handler的正確使用與解析

Android效能優化之handler的正確使用與解析

1.什麼是Handler

    是Android訊息機制的上層介面,是一種更新ui的機制。
   (Android是執行緒不安全的,所以能在子執行緒更新ui,只能執行耗時操作 ,所以要通過handler傳送訊息更新)

2.Handler實現原理

ThreadLocal:通過不同的執行緒訪問同一個ThreadLocal,無論是ThreadLocal的get或set方法,它們對ThreadLocal的讀寫操作都僅限於各自執行緒內部。
通過ThreadLocal儲存Looper(保證handler中的每個Looper是相互獨立的,且不同的執行緒訪問不同的Looper)
Looper是內部管理MessgeQueue的。

每一個handler要與主執行緒關聯上,才可以更新ui。不能在內部類建立handler。這樣才能保證ui執行緒是執行緒安全。

(就小小的借鑑一下另一位博主的圖展示一下handler的流程,個人覺得還是蠻好的)


3.Handler記憶體洩露問題


產生記憶體洩露原因:靜態內部類持有外部類的匿名使用,導致在使用者退出當前Activity時,handler內部的一些耗時操作還在執行,從而導致activity還被handler做引用,最終導致activity還存留在堆疊中,沒有被回收,導致記憶體洩露。

解決:1.handler內部持有外部activity的弱引用。
             2.把handler改為靜態內部類。
             3.在activity的onDestory方法內掉用mHandler.removeCallBack()。

           (只能90%的解決)

解決例項:

/**
 * 解決方式
 *
 * 要解決這種問題,思路就是不適用非靜態內部類,繼承Handler時,要麼是放在單獨的類檔案中,要麼就是使用靜態內部類。
 * 因為靜態的內部類不會持有外部類的引用,所以不會導致外部類例項的記憶體洩露。
 * 當你需要在靜態內部類中呼叫外部的Activity時,我們可以使用弱引用來處理。
 * 另外關於同樣也需要將Runnable設定為靜態的成員屬性。
 * 注意:一個靜態的匿名內部類例項不會持有外部類的引用。
 */
private MyHandler mMyHandler = new MyHandler(this);

private static class 
MyHandler extends Handler{ // SoftReference<Activity> 也可以使用軟應用 只有在記憶體不足的時候才會被回收 private final WeakReference<Activity> mActivity; private MyHandler(Activity activity) { mActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { Activity activity = mActivity.get(); if (activity != null){ //做操作 } super.handleMessage(msg); } } private static final Runnable sRunnable = new Runnable() { @Override public void run() { //做操作 } };

感覺還不錯的,點個讚唄微笑