lifecycle官方文檔地址:
https://developer.android.com/topic/libraries/architecture/lifecyclehtml
activity 和fragment 是有聲明週期的,有時候,咱們的不少操做須要寫在聲明週期的方法中,好比,下載,文件操做等,這樣不少狀況下回致使,咱們在activity中的聲明週期方法中寫愈來愈多的代碼,activity或者fragment 愈來愈臃腫,代碼維護愈來愈困難。 使用lifecycle就能夠很好的解決這類問題。
lifecycle代碼簡潔,咱們能夠經過實現LifecycleObserver 接口,來監聽聲明週期,而後咱們在activity和fragment中去註冊監聽。
官網介紹: LifecycleOwner是一個單一的方法接口,表示該類有一個 Lifecycle。它有一個方法, getLifecycle()這個方法 必須由這個類來實現。若是您試圖管理整個應用程序進程的生命週期,請參閱 ProcessLifecycleOwner。該接口從各個類(如Fragment和AppCompatActivity)抽象生命週期的全部權,並容許編寫與它們一塊兒工做的組件。
任何自定義應用程序類均可以實現LifecycleOwner接口
實現LifecycleObserver的組件與實現LifecycleOwner的組件無縫協做,由於全部者能夠提供生命週期,觀察者能夠註冊以觀看
簡單來講,LifecycleOwner就是一個接口,誰繼承了它,就持有了lifecycle對象。而後就能夠調用getLifecycle()方法獲取繼承了抽象類Lifecycle的LifecycleRegistry,而後調用 addObserver(@NonNull LifecycleObserver observer) 方法來註冊監聽。
這樣,該接口的生命週期(Lifecycle對象)的改變會被其註冊的觀察者LifecycleObserver觀察到並觸發其對應的事件。java
注意:Support Library 26.1.0 及其之後的版本,Activity 和Fragment 已經實現了LifecycleOwner 接口,因此,咱們能夠直接在Activity 和Fragment中使用getLifecycle()方法來獲取lifecycle對象,來添加觀察者監聽。android
LifecycleObserver 是一個觀察者接口,實現了它,能夠經過註解或者繼承的方式,來管理聲明週期的監聽。只要在持有lifecycle的類中註冊了它,當聲明週期發生變化時,它就能收到,進行咱們自定義的操做。
兩種實現方式:編程
Lifecycle.java文檔中是建議使用第一種方式,由於文檔中說明了,隨着Java8成爲主流,註解的方式會被棄用。DefaultLifecycleObserver是須要另外聲明的java8 好比下面
GenericLifecycleObserver,FullLifecycleObserver,DefaultLifecycleObserver 這三個接口都是直接或者間接繼承的LifecycleObserverapi
// 若是使用的是java 8要顯示聲明以下的 def lifecycle_version = "1.1.1" implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
咱們寫個測試代碼,首先,咱們要測試一下,到底LifecycleObserver到底能不能監聽到聲明週期的變化。而且實驗下上圖中的聲明週期狀態
先寫兩個簡單的Activity,FirstActivity 和SecondActivity, 單純的一個跳轉。網絡
public class FirstActivity extends AppCompatActivity { private Button firstBtn; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_activity_layout); initView(); initListener(); } private void initView() { firstBtn = findViewById(R.id.first_btn); } private void initListener() { firstBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity(intent); } }); } }
接下來,咱們要作的是要寫一個須要擁有聲明週期的類,正常咱們自定義控件啊,或者作其餘邏輯的類,是沒有聲明週期的,如今有了LifecycleObserver,咱們可讓一個普通的類擁有感知聲明週期變化的能力。好比,如今自定義一個,MyObserver類。框架
public class MyObserver implements DefaultLifecycleObserver{ private static final String TAG = "MyListener"; @Override public void onCreate(@NonNull LifecycleOwner owner) { Log.d(TAG,"onCreate()"); Log.d(TAG,"當前生命週期狀態="+lifecycle.getCurrentState().name()); } @Override public void onStart(@NonNull LifecycleOwner owner) { Log.d(TAG,"onStart()"); Log.d(TAG,"當前生命週期狀態="+lifecycle.getCurrentState().name()); } @Override public void onResume(@NonNull LifecycleOwner owner) { Log.d(TAG,"onResume()"); Log.d(TAG,"當前生命週期狀態="+lifecycle.getCurrentState().name()); } @Override public void onPause(@NonNull LifecycleOwner owner) { Log.d(TAG,"onPause()"); Log.d(TAG,"當前生命週期狀態="+lifecycle.getCurrentState().name()); } @Override public void onStop(@NonNull LifecycleOwner owner) { Log.d(TAG,"onStop()"); Log.d(TAG,"當前生命週期狀態="+lifecycle.getCurrentState().name()); } @Override public void onDestroy(@NonNull LifecycleOwner owner) { Log.d(TAG,"onDestroy() "); Log.d(TAG,"當前生命週期狀態="+lifecycle.getCurrentState().name()); } }
咱們採起的是,直接繼承DefaultLifecycleObserver接口,來實現它全部的方法。咱們在裏面作了log,來查看,是否這個類,收到了activity聲明週期的變化。
而後,要作的就是註冊監聽
在Activity 的OnCreate方法中,調用getLifecycle();編程語言
public class FirstActivity extends AppCompatActivity { private Button firstBtn; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_activity_layout); initView(); initListener(); //添加了這一行代碼 getLifecycle().addObserver(new MyObserver()); } private void initView() { firstBtn = findViewById(R.id.first_btn); } private void initListener() { firstBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity(intent); } }); } }
能夠看到,api26,.1之後,Activity中能夠直接 getLifecycle().addObserver(new MyObserver()); 這樣,就已經註冊了聲明週期觀察者的監聽。運行查看log
啓動FirstActivity後,MyObserver類已經監聽到了Activity的聲明週期方法
而且,和圖中表示一致,各個聲明週期方法對應相應的節點。必定要清楚,後面會用到。好比,onResume()方法執行後,Activity處於RESUME狀態,咱們能夠經過判斷這個狀態來作一些事情ide
點擊跳轉到SecondActivity
能夠看到,FirstActivity聲明週期走了onPause onStop,MyObserver也成功監聽到了,繼續返回FirstActivity
最後,點擊返回鍵,退出FirstActivity,
測試
經過這個簡單的小例子,咱們看到了 咱們的類,只要實現了 LifecycleObserver接口,而後,在Activity 或者Fragment中 經過getLifecycle().addObserver()方法,把這個類的對象傳入,就能夠實現聲明週期的感應監聽。
固然,咱們能夠再初始化這個類的時候,把Lifecycle對象傳入,那咱們自定義的類就能夠本身去管理聲明週期,而不依賴activity或者fragment。 這樣,activity在使用此類的時候就沒必要關係聲明週期的問題,由於,在這個類裏面咱們已經處理了。好比: 給MyObserver類 添加一個構造方法,傳入一個Lifecycle對象。
要注意的是:
生命週期狀態爲RESUMED時表示,當前activity 是在前臺,而且可交互也就是onResume()執行後
生命週期狀態爲STARTED時,表示當前activity處於可見可是不可交互,也就是onStart()方法剛執行完或者onPause()方法剛執行完的狀態
生命週期狀態爲CREATED,表示onCreate()方法剛剛執行完或者onStop()方法剛剛執行完,也就是當前activity不在前臺,可是也沒有處於銷燬狀態。
生命週期狀態爲DESTORYED,表示當前Activity還不存在,沒有被建立或者已經銷燬,咱們一般考慮比較多的就是,onDestory()方法執行後,當前Activity已經銷燬。
因此,若是咱們要保證在Activity或者Fragment的有效生命週期內進行的操做,必須判斷,當前lifecycle的狀態是否至少是CREATED狀態,避免Activity或者fragment銷燬了之後,回調或者網絡請求才回來,此時作一些操做會致使異常。
添加如下代碼,就是咱們把lifecycle對象傳給觀察者,讓它本身去判斷回調後的代碼,保證至少是CREATED狀態
private Lifecycle lifecycle; public MyObserver(Lifecycle lifecycle) { this.lifecycle = lifecycle; } //而後再相應的回調方法中使用下面代碼判斷,保證數據回調回來,當前activity是存在的 if (lifecycle.getCurrentState().isAtLeast(CREATED)) { //這裏只是示例,不必定是CREATED }
這裏用到了Lifecycle類的方法,下面咱們看一下Lifecycle的源碼
public abstract class Lifecycle { @MainThread //添加將在LifecycleOwner更改狀態時通知的LifecycleObserver。 public abstract void addObserver(@NonNull LifecycleObserver observer); @MainThread //從觀察者列表中刪除給定的觀察者。 public abstract void removeObserver(@NonNull LifecycleObserver observer); @MainThread //返回生命週期的當前狀態。 public abstract State getCurrentState(); @SuppressWarnings("WeakerAccess") public enum Event { ON_CREATE,//用於onCreate事件的常量LifecycleOwner。 ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_ANY //一個Event能夠用來匹配全部事件的常數。 } @SuppressWarnings("WeakerAccess") public enum State { DESTROYED, INITIALIZED, //LifecycleOwner的初始化狀態。 CREATED, STARTED, RESUMED; //比較此狀態是否大於或等於給定值state。 public boolean isAtLeast(@NonNull State state) { return compareTo(state) >= 0; } } } /** * Marks a class as a LifecycleObserver. It does not have any methods, instead, relies on * {@link OnLifecycleEvent} annotated methods. * <p> * @see Lifecycle Lifecycle - for samples and usage patterns. */ @SuppressWarnings("WeakerAccess") public interface LifecycleObserver { }
就是一個抽象類,註釋已經很詳細了,應該不用解釋了
最後借用下官網的-生命週期感知組件的最佳實戰
若是你喜歡用Java編程語言來作到這一點,可使用像Butter Knife這樣的庫來避免樣板代碼而且有更好的抽象。
若是ViewModel超出活動(在配置更改的狀況下),則活動會泄漏而且垃圾收集器沒法正確處理。
借用下https://blog.csdn.net/zhuzp_b... 做者的兩張圖,更清晰,對於相信信息,可到做者博客去查看相關講解