Lifecycle解決Dialog記憶體洩漏的問題

語言: CN / TW / HK

highlight: a11y-dark theme: condensed-night-purple


持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第4天,點選檢視活動詳情

Dialog是安卓開發中常用的元件之一,但是它的使用過程中會出現一個問題。當我們activity關閉時,若Dialog沒有關閉會導致記憶體洩漏。記憶體洩漏其實比較好處理,只需要當activity關閉時銷燬Dialog就行。但是如果關閉銷燬Dialog的邏輯可能比較複雜,而利用Jetpack中的Lifecycle可以比較完美的解決Dialog記憶體洩漏的問題。

Lifecycle是什麼?

Lifecycle是Jetpack用來感知生命週期的元件,使用Lifecycle可以幫助我們寫出與生命週期相關且更簡潔,容易後期維護的程式碼。Lifecycle可以通過在activity註冊觀察者從而感知到當前頁面的生命週期,進而對相應生命週期方法中的邏輯進行抽離。將業務邏輯和activity剝離,使得程式碼簡潔且適合後期維護。

為什麼Lifecycle可以用來監聽Dialog的生命週期:

因為Dialog都是需要依附於一個activity,這個主要是因為安卓底層繪製原理所決定的。一個窗體(Window)對應一個繪製圖層,phoneWindow作為主繪製圖層其他的圖層需要依附於它,並且渲染時所有窗體的檢視資料必須都寫進圖形緩衝區裡面,因此Dialog必須依附於activity。既然Dialog依附於activity,那麼就意味著Dialog可以通過Lifecycle去感知acitivity的生命週期,進而對自己的狀態進行管理。

Lifecycle怎麼寫一個不會記憶體洩漏的Dialog

如下方程式碼就實現了當Dialog所依附的acitivity銷燬時,Dialog也隨之關閉,這樣記憶體洩漏的問題就不存在了。

``` class TipDialog(context: Context) Dialog ( context ), LifecycleObserver { init { if (context is componentActivity) { (context as componentActivity).lifecycle.addObserver(this)

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstancestate)
            setContentView(R.layout.item_tip_dialog)

            @OnLifecycleEvent(Lifecycle.Event.ON_DESTRoY) 
            private fun onDestroy() {
                if (isShowing) {
                    dismiss()
                }
            }
        }

```

由於在實際使用中Dialog可能不僅僅存在記憶體洩漏的問題,所以需要開發者根據實際情況在Activity的生命週期方法中做處理。

感謝您的閱讀,專注才能提高學習效率,peace!