Android Jetpack 架構組件之 Lifecycle (一)起源

Lifecycle的存在乎義

文章開頭先來引入一個 業務案例安全

這是一個學習英語的App,部分頁面支持 劃詞播放markdown

如何能夠優雅得實現這個真實的業務場景呢?架構

首先須要定義一個全局單例的播放器,播放器有一個方法play(val content: String)ide

object ContentPlayer {
    
    fun play(content: String) {
        //調用系統播放器播放 
    }
    
    fun prepare(context: Context) {
        //播放器的準備工做
    }
}
複製代碼

實現ContentPlayer以後,就能夠在支持劃詞播放功能的Activity的劃詞事件回調中這樣寫:post

class ContentActivity : AppCompatActivity(), UnderLineWordCallBack {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        ContentPlayer.prepare(this)
    }
    
	//當前Activity的劃詞播放後回調這裏
    override fun callback(content: String) {
    	// 開始播放
        ContentPlayer.play(content)
    }

}
複製代碼

這樣這個功能就作完了。真得作完了嗎?若是你的Leader看到這樣的代碼,怕不是次日讓你捲鋪蓋走人~(開玩笑的開玩笑的)學習

這樣的代碼可能會發生 內存泄漏
假設客戶劃了一段很長的英語文章,而後點擊播放,播放到一半客戶不想聽了,直接點擊了返回鍵後,播放器還持有着 ContentActivity的引用,在播放器繼續播放的過程當中,ContentActivity是沒法被gc的,這就會出現了問題優化

因此咱們還須要準備一個unAttach()方法。最終的方案以下:this

object ContentPlayer{

    fun play(content: String) {
        //調用系統播放器播放
    }

    fun prepare(context: Context) {
        //播放器的準備工做
    }
    
    fun unAttach() {
        //釋放當前持有的Activity資源 
    }
}
複製代碼
class ContentActivity : AppCompatActivity(), UnderLineWordCallBack {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        //準備播放器資源
        ContentPlayer.prepare(this)
    }
    
	//當前Activity的劃詞播放後回調這裏
    override fun callback(content: String) {
    	// 開始播放
        ContentPlayer.play(content)
    }
    
    override fun onDestory() {
        ...
        // 釋放資源
        ContentPlayer.unAttach()
    }

}
複製代碼

上面這樣的代碼固然沒有問題了,能夠正常使用,咱們還嚴謹的保護了App不發生內存泄漏,值得表揚!spa

可是還有問題:code

  • 沒法保證調用一致性,在多人協做開發時存在很大的隱患
  • 調用不夠優雅
  • 代碼侵入型太強

若是當前App有不少的Activity要用到劃詞播放這個功能,那麼咱們就須要在每個Activity中重複上面的代碼,當代碼量上來以後,會很容易遺忘調用unAttach方法,並且一個項目不多是以後一我的完成,每每是協做開發,若是別人寫的界面想要調用你寫的ContentPlayer,除非你寫了很詳細的註釋,不然必須深刻源碼,才知道在Activity的onDestory處去釋放資源。

更優雅,更安全的寫法,就是利用Lifecycle組件

Lifecycle的出現如何解決問題

在進一步使用Lifecycle優化上述代碼以前,先看一下Lifecycle的官方定義:

生命週期感知型組件可執行操做來響應另外一個組件(如 Activity 和 Fragment)的生命週期狀態的變化。這些組件有助於您寫出更有條理且每每更精簡的代碼,這樣的代碼更易於維護。

也就是說,咱們寫代碼中開發的某個組件須要去感知生命週期時,要首先想到使用Lifecycle。

可讓咱們在組件內部來監聽到生命週期,就像這樣:

object ContentPlayer : LifecycleObserver{

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun prepare(context: Context) {
        //播放器的準備工做
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun unAttach() {
        //釋放當前持有的Activity資源
    }
}
複製代碼

經過方法註解,決定當前方法被調用的時機。以後在須要使用ContentPlayer的Activity中去註冊觀察者

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 一行代碼搞定
        lifecycle.addObserver(ContentPlayer)
    }
複製代碼

用到劃詞播放的界面只需經過一行代碼,lifecycle.addObserver(ContentPlayer)註冊lifecycle觀察者。完美解決了調用一致性和代碼侵入性太強的問題。

Lifecycle給其餘Jectpack相關組件鋪路

Lifecycle除了給咱們開發者使用以外,在Android源碼很 Lifecycle組件是Google Jectpack架構的基礎,Jectpack的組件:databing、viewmodel等等都依賴於lifecycle對生命週期的感知,因此我認爲在學習jectpack和MVVM以前,須要先了解一下Lifecycle的使用和 基本實現原理

相關文章
相關標籤/搜索