- Android Jetpack應用指南
- 葉坤
- 931字
- 2020-08-06 15:42:29
2.2 使用LifeCycle解耦頁面與組件
2.2.1 案例分析
假設有這樣一個常見的需求:在用戶打開某個頁面時,獲取用戶當前的地理位置。面對該需求,我們通常會這樣寫代碼。


從以上代碼可以看出,獲取地理位置這個需求的實現,與頁面的生命周期息息相關。如果我們希望將獲取地理位置這一功能獨立成一個組件,那么生命周期是必須要考慮在內的。我們不得不在頁面生命周期的各個回調方法中,對組件進行通知,因為組件不能主動感知生命周期的變化。
2.2.2 LifeCycIe的原理
LifeCycle是如何解決這個問題的呢?Jetpack為我們提供了兩個類:LifecycleOwner(被觀察者)和LifecycleObserver(觀察者)。即通過觀察者模式,實現對頁面生命周期的監聽。
通過查看SupportActivity的源碼,可以看到,在新版本的SDK包中,Activity已經默認實現了LifecycleOwner接口。LifecycleOwner接口中只有一個getLifecycle(LifecycleObserver observer)方法,LifecycleOwner正是通過該方法實現觀察者模式的。源碼示例如下。

從以上源碼可知,SupportActivity已經替我們實現了被觀察者應該實現的那一部分代碼。因此,我們不需要再去實現這部分代碼。當我們希望監聽Activity的生命周期時,只需要實現觀察者那一部分的代碼,即讓自定義組件實現LifecycleObserver接口即可。該接口沒有接口方法,無須任何具體實現。
2.2.3 解決方案
現在,讓我們利用LifeCycle改寫該需求。我們的目的是將該功能從Activity中獨立出去,在減少耦合度的同時,又不影響對生命周期的監聽。
1.編寫一個名為MyLocationListener的類。該類就是我們的自定義組件,我們需要讓該組件實現LifecycleObserver接口。與獲取地理位置相關的代碼在該類中完成。
對于組件中那些需要在頁面生命周期發生變化時得到通知的方法,我們需要在這些方法上使用@OnLifecycleEvent(Lifecycle.Event.ON_XXX)標簽進行標識。這樣,當頁面生命周期發生變化時,這些被標識過的方法便會被自動調用。如下所示。


2.在MainActivity中,只需要引用MyLocationListener即可,不用再關心Activity生命周期變化對該組件所帶來的影響。生命周期的管理完全交給MyLocationListener內部自行處理。在Activity中要做的只是通過getLifecycle().addObserver()方法,將觀察者與被觀察者綁定起來,代碼如下所示。

就這么簡單!LifeCycle完美解決了組件對頁面生命周期的依賴問題,使組件能夠自己管理其生命周期,而無須在頁面中對其進行管理。這無疑大大降低了代碼的耦合度,提高了組件的復用程度,也杜絕了由于對頁面生命周期管理的疏忽而引發的內存泄漏問題,這在項目工程量大的情況下是非常有幫助的。
除Activity之外,在新版本的SDK中,Fragment同樣也默認實現了LifecycleOwner接口。因此,以上案例同樣適用于Fragment。Fragment的源碼如下所示。
