什麼是 Lifecycle-aware Components?
Lifecycle-ware components(生命週期感知元件)包含在 android.arch.lifecycle 套件中,基本上就是當元件(Activity or Service)的生命週期發生變化時,生命週期元件即會自動收到通知並觸發相對應的動作。
為什麼需要生命週期感知元件?
在此之前若開發者需要根據元件的生命週期執行相對應的動作時都必須寫在元件的對應方法中。最常見的例子為旋轉螢幕時需要儲存資料,不是寫在 onPause 方法就是寫在 onSaveInstanceState 方法。
但這種寫法最直接的缺點就是增加 Activity 的大小,讓 Activity 變得越來越大。
生命週期感知元件可以根據 Activity 或 Fragment 的當前生命週期狀態自動呼叫其行為。
Lifecycle
Lifecycle 是一個類別,擁有關於另一個元件(Activity or Fragment)生命週期狀態的資訊。
Lifecycle 使用 2 個列舉來追蹤其相關連元件的生命週期狀態:
1.Event(事件)
Event 透過 Framework 和 Lifecycle class 發送,Event 會對應於 Activity 或 Fragment 的回調事件(callback events)。
2.State(狀態)
相關連元件的當前狀態。
以下為 Event 和 State 兩者互相轉換的關係圖。
LifecycleOwner
LifecycleOwner 為只有一個方法的介面,該方法必須回傳 Lifecycle。
在 Support Library 26.1.0 已將 Activity 和 Fragment 繼承 LifecycleOwner 並寫好回傳 Lifecycle 的實作部分,也就是說 Activity 和 Fragment 就是 LifecycleOwner。
要自動感知 Activity 的生命週期,首先呼叫 getLifecycle 方法取得 Lifecycle,接著再呼叫 Lifecycle 的 addObserver 方法讓 LifecycleObserver 訂閱 Lifecycle。
基本上就是透過 LifecycleOwner 提供 Lifecycle,接著讓 LifecycleObserver 訂閱
Lifecycle,如此 LifecycleObserver 就能感知 Lifecycle 的變化。
LifecycleObserver
LifecycleObserver 的用途就是用來跟蹤繼承 LifecycleOwner 的元件,透過在方法上加上註解的方式,可以自動取得目標元件的相關生命週期變化。
一個最簡單用來感知 Activity 的 LifecycleObserver 如下
import android.arch.lifecycle.Lifecycle; import android.arch.lifecycle.Lifecycle.Event; import android.arch.lifecycle.LifecycleObserver; import android.arch.lifecycle.OnLifecycleEvent; import android.content.Context; import android.util.Log; public class LifecycleMainActivityObserver implements LifecycleObserver { private static final String TAG = LifecycleMainActivityObserver.class.getSimpleName(); @OnLifecycleEvent(Event.ON_START) public void lifecycleStart() { Log.d(TAG, "detect lifecycle on start"); } @OnLifecycleEvent(Event.ON_CREATE) public void lifecycleCreate() { Log.d(TAG, "detect lifecycle on create"); } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void lifecycleResume() { Log.d(TAG, "detect lifecycle on resume"); } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void lifecyclePause() { Log.d(TAG, "detect lifecycle on pause"); } @OnLifecycleEvent(Event.ON_STOP) public void lifecycleStop() { Log.d(TAG, "detect lifecycle on stop"); } @OnLifecycleEvent(Event.ON_DESTROY) public void lifecycleDestroy() { Log.d(TAG, "detect lifecycle on destroy"); } @OnLifecycleEvent(Event.ON_ANY) public void lifecycleChange() { Log.d(TAG, "detect lifecycle change"); } }
註解 OnLifecycleEvent(Event.ON_CREATE) 就表示當目標元件處於 create 狀態時,該方法便會被呼叫。
接著只要在目標元件的 onCreate 方法初始化 observer,並呼叫 addObserver() 即可
public class LifecycleMainActivity extends AppCompatActivity { private LifecycleMainActivityObserver mLifecycleMainActivityObserver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lifecycle_main_activity); mLifecycleMainActivityObserver = new LifecycleMainActivityObserver(); getLifecycle().addObserver(mLifecycleMainActivityObserver); } }
最後 LifecycleMainActivityObserver 的方法便會對應 LifecycleMainActivity 的生命週期改變自動被呼叫。
關於生命感知週期元件的最佳實踐
1.保持 UI Controllers(Activity or Fragment)盡量精簡,它們不該存取自己的資料,而應該交由 ViewModel 來執行,並透過 LiveData 將資料的變更反射回 View。
2.嘗試實作數據驅動的 UI,其中 UI Controller 負責在數據更改時更新視圖,或將用戶操作通知給 ViewModel。
3.應該將數據邏輯放到 ViewModel,把 ViewModel 當作 UI 和其他元件的連接器且 ViewModel 不應該去直接獲取數據(如本地端資料庫,遠端網路)。而是透過其它元件來取得數據,再返回給 UI controller。
4.使用 Data Binding 來建立 View 和 UI Controller 之間的簡潔介面,可讓 View 更具聲明性並大量的減少在 Activity 和 Fragment 需要寫的代碼。也可以考慮使用 Butter Knife 來避免樣版代碼以及建立良好的抽象。
5.若 UI 非常複雜可以考慮建立 Presenter 來處理 UI 的變化。
6.不要在 ViewModel 中引用 View 或 Activity context,否則可能造成記憶體洩漏。
生命感知週期的使用案例
1.動畫,當 App 位於後台時停止動畫,返回前台時恢復動畫
2.網路連接,當 App 位於後台時暫停網路,返回前台時恢復網路
3.視頻緩衝,當 App 啟動時盡快啟動緩衝,但直到App完全啟動時再播放視頻。可在App銷毀時終止視頻緩衝。
4.位置更新,當 App 位於後台時使用粗粒度位置更新,返回前台時使用細粒度位置更新。
Article Comments