Android效能優化之handler的正確使用與解析
阿新 • • 發佈:2019-02-16
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 classMyHandler 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() { //做操作 } };
感覺還不錯的,點個讚唄