由於 Handler 屬於 TLS(Thread Local Storage)變數,導致它的生命周期和 Activity 不一致。因此通過 Handler 來更新 UI 一般很難保證跟 View 或者 Activity 的生命周期一致,故很容易導致無法正確釋放。
上面的代碼中發送了了一個延時 5 分鐘執行的 Message,當該 Activity 退出的時候,延時任務(Message)還在主線程的 MessageQueue 中等待,此時的 Message 持有 Handler 的強引用
(創建時通過 Message.target 進行指定),並且由於 Handler 是 HandlerBadActivity 的非靜態內部類
,所以 Handler 會持有一個指向 HandlerBadActivity 的強引用
,所以雖然此時 HandlerBadActivity 調用了 finish 也無法進行內存回收,造成內存泄漏。
不要在類初始化時初始化靜態成員,也就是可以考慮懶載入。架構設計上要思考是否真的有必要這樣做,盡量避免。如果架構需要這麼設計,那麼此對象的生命周期你有責任管理起來。
當然,Application 的 context 不是萬能的,所以也不能隨便亂用,對於有些地方則必須使用 Activity 的 Context,對於Application,Service,Activity三者的Context的應用場景如下: