首頁>技術>

此事件回撥中這樣寫:

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()方法。最終的方案如下:

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不發生記憶體洩漏,值得表揚!

但是還有問題:

無法保證呼叫一致性,在多人協作開發時存在很大的隱患呼叫不夠優雅程式碼侵入性太強

如果當前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的使用和 基本實現原理

11
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Jetpack 架構元件之 Lifecycle (二) 使用