**已經(jīng)融入: **MonkeyLei:Android_組件化MVVM組件化+LiveData+ViewModel+Repository
有相關(guān)接口DefaultLifecycleObserver無法使用的可以參考: androidx.lifecycle..DefaultLifecycleObserver not found ( 一般采用最新的方式,之前依賴了ViewModel的話,只需要像上面工程配置依賴下java8的就可以了。Lifecycle | Android 開發(fā)者 | Android Developers - 這是對應(yīng)的依賴參考; arch已經(jīng)逐漸拋棄了。。)另外官方建議不用注解,采用繼承方式比較好!
同時(shí): androidx.lifecycle " lifecycle-common-java8 這是官方的最新的java8的common版本信息,供參考
1、Lifecycle介紹
lifecycle官方文檔地址:
https://developer.android.com/topic/libraries/architecture/lifecycle
為什么要使用lifecycle?
activity 和fragment 是有聲明周期的,有時(shí)候,我們的很多操作需要寫在聲明周期的方法中,比如,下載,文件操作等,這樣很多情況下回導(dǎo)致,我們在activity中的聲明周期方法中寫越來越多的代碼,activity或者fragment 越來越臃腫,代碼維護(hù)越來越困難。 使用lifecycle就可以很好的解決這類問題。
lifecycle代碼簡潔,我們可以通過實(shí)現(xiàn)LifecycleObserver 接口,來監(jiān)聽聲明周期,然后我們在activity和fragment中去注冊監(jiān)聽。
2、幾個(gè)重要的類和接口
-
Lifecycle
Lifecycle是一個(gè)持有組件生命周期狀態(tài)(如Activity或Fragment)的信息的類,并允許其他對象觀察此狀態(tài)。 - Event :從框架和Lifecycle類派發(fā)的生命周期事件。這些事件映射到活動和片段中的回調(diào)事件。
- State :由Lifecycle對象跟蹤的組件的當(dāng)前狀態(tài)。
- LifecycleOwner (重要)Lifecycle持有者
- 實(shí)現(xiàn)該接口的類持有生命周期(Lifecycle對象),該接口的生命周期(Lifecycle對象)的改變會被其注冊的觀察者LifecycleObserver觀察到并觸發(fā)其對應(yīng)的事件。
- LifecycleObserver(重要)Lifecycle觀察者
- 實(shí)現(xiàn)該接口的類,通過注解的方式,可以通過被LifecycleOwner類的addObserver(LifecycleObserver o)方法注冊,被注冊后,LifecycleObserver便可以觀察到LifecycleOwner的生命周期事件。
3、LifeCycle中兩個(gè)重要的接口LifeCycleOwner和LifecycleObserver 的使用
(1)LifecycleOwner(生命周期持有者接口)
官網(wǎng)介紹:LifecycleOwner是一個(gè)單一的方法接口,表示該類有一個(gè) Lifecycle。它有一個(gè)方法,getLifecycle()這個(gè)方法 必須由這個(gè)類來實(shí)現(xiàn)。如果您試圖管理整個(gè)應(yīng)用程序進(jìn)程的生命周期,請參閱 ProcessLifecycleOwner。該接口從各個(gè)類(如Fragment和AppCompatActivity)抽象生命周期的所有權(quán),并允許編寫與它們一起工作的組件。
任何自定義應(yīng)用程序類都可以實(shí)現(xiàn)LifecycleOwner接口
實(shí)現(xiàn)LifecycleObserver的組件與實(shí)現(xiàn)LifecycleOwner的組件無縫協(xié)作,因?yàn)樗姓呖梢蕴峁┥芷?,觀察者可以注冊以觀看
簡單來說,LifecycleOwner就是一個(gè)接口,誰繼承了它,就持有了lifecycle對象。然后就可以調(diào)用getLifecycle()方法獲取繼承了抽象類Lifecycle的LifecycleRegistry,然后調(diào)用 addObserver(@NonNull LifecycleObserver observer) 方法來注冊監(jiān)聽。
這樣,該接口的生命周期(Lifecycle對象)的改變會被其注冊的觀察者LifecycleObserver觀察到并觸發(fā)其對應(yīng)的事件。
注意:Support Library 26.1.0 及其以后的版本,Activity 和Fragment 已經(jīng)實(shí)現(xiàn)了LifecycleOwner 接口,所以,我們可以直接在Activity 和Fragment中使用getLifecycle()方法來獲取lifecycle對象,來添加觀察者監(jiān)聽。
(2)LifecycleObserver(生命周期觀察者接口)
LifecycleObserver 是一個(gè)觀察者接口,實(shí)現(xiàn)了它,可以通過注解或者繼承的方式,來管理聲明周期的監(jiān)聽。只要在持有l(wèi)ifecycle的類中注冊了它,當(dāng)聲明周期發(fā)生變化時(shí),它就能收到,進(jìn)行我們自定義的操作。
兩種實(shí)現(xiàn)方式:
- 實(shí)現(xiàn)DefultLifecyceObserver接口,然后重寫里面生命周期方法;
- 直接實(shí)現(xiàn)LifecycleObserver接口,然后通過注解的方式來接收生命周期的變化;
Lifecycle.java文檔中是建議使用第一種方式,因?yàn)槲臋n中說明了,隨著Java8成為主流,注解的方式會被棄用。DefaultLifecycleObserver是需要另外聲明的java8 比如下面
GenericLifecycleObserver,F(xiàn)ullLifecycleObserver,DefaultLifecycleObserver 這三個(gè)接口都是直接或者間接繼承的LifecycleObserver
// 如果使用的是java 8要顯示聲明如下的
def lifecycle_version = "1.1.1"
implementation "android.arch.lifecycle:common-java8:$lifecycle_version"

3、開始使用Lifecycle
我們寫個(gè)測試代碼,首先,我們要測試一下,到底LifecycleObserver到底能不能監(jiān)聽到聲明周期的變化。并且實(shí)驗(yàn)下上圖中的聲明周期狀態(tài)
先寫兩個(gè)簡單的Activity,F(xiàn)irstActivity 和SecondActivity, 單純的一個(gè)跳轉(zhuǎn)。
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);
}
});
}
}
接下來,我們要做的是要寫一個(gè)需要擁有聲明周期的類,正常我們自定義控件啊,或者做其他邏輯的類,是沒有聲明周期的,現(xiàn)在有了LifecycleObserver,我們可以讓一個(gè)普通的類擁有感知聲明周期變化的能力。比如,現(xiàn)在自定義一個(gè),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,"當(dāng)前生命周期狀態(tài)="+lifecycle.getCurrentState().name());
}
@Override
public void onStart(@NonNull LifecycleOwner owner) {
Log.d(TAG,"onStart()");
Log.d(TAG,"當(dāng)前生命周期狀態(tài)="+lifecycle.getCurrentState().name());
}
@Override
public void onResume(@NonNull LifecycleOwner owner) {
Log.d(TAG,"onResume()");
Log.d(TAG,"當(dāng)前生命周期狀態(tài)="+lifecycle.getCurrentState().name());
}
@Override
public void onPause(@NonNull LifecycleOwner owner) {
Log.d(TAG,"onPause()");
Log.d(TAG,"當(dāng)前生命周期狀態(tài)="+lifecycle.getCurrentState().name());
}
@Override
public void onStop(@NonNull LifecycleOwner owner) {
Log.d(TAG,"onStop()");
Log.d(TAG,"當(dāng)前生命周期狀態(tài)="+lifecycle.getCurrentState().name());
}
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
Log.d(TAG,"onDestroy() ");
Log.d(TAG,"當(dāng)前生命周期狀態(tài)="+lifecycle.getCurrentState().name());
}
}
我們采取的是,直接繼承DefaultLifecycleObserver接口,來實(shí)現(xiàn)它所有的方法。我們在里面做了log,來查看,是否這個(gè)類,收到了activity聲明周期的變化。
然后,要做的就是注冊監(jiān)聽
在Activity 的OnCreate方法中,調(diào)用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()); 這樣,就已經(jīng)注冊了聲明周期觀察者的監(jiān)聽。運(yùn)行查看log
啟動FirstActivity后,MyObserver類已經(jīng)監(jiān)聽到了Activity的聲明周期方法
并且,和圖中表示一致,各個(gè)聲明周期方法對應(yīng)相應(yīng)的節(jié)點(diǎn)。一定要清楚,后面會用到。比如,onResume()方法執(zhí)行后,Activity處于RESUME狀態(tài),我們可以通過判斷這個(gè)狀態(tài)來做一些事情

點(diǎn)擊跳轉(zhuǎn)到SecondActivity

可以看到,F(xiàn)irstActivity聲明周期走了onPause onStop,MyObserver也成功監(jiān)聽到了,繼續(xù)返回FirstActivity

最后,點(diǎn)擊返回鍵,退出FirstActivity,

通過這個(gè)簡單的小例子,我們看到了 我們的類,只要實(shí)現(xiàn)了 LifecycleObserver接口,然后,在Activity 或者Fragment中 通過getLifecycle().addObserver()方法,把這個(gè)類的對象傳入,就可以實(shí)現(xiàn)聲明周期的感應(yīng)監(jiān)聽。
當(dāng)然,我們可以再初始化這個(gè)類的時(shí)候,把Lifecycle對象傳入,那我們自定義的類就可以自己去管理聲明周期,而不依賴activity或者fragment。 這樣,activity在使用此類的時(shí)候就不必關(guān)系聲明周期的問題,因?yàn)椋谶@個(gè)類里面我們已經(jīng)處理了。比如: 給MyObserver類 添加一個(gè)構(gòu)造方法,傳入一個(gè)Lifecycle對象。
要注意的是:
生命周期狀態(tài)為RESUMED時(shí)表示,當(dāng)前activity 是在前臺,并且可交互也就是onResume()執(zhí)行后
生命周期狀態(tài)為STARTED時(shí),表示當(dāng)前activity處于可見但是不可交互,也就是onStart()方法剛執(zhí)行完或者onPause()方法剛執(zhí)行完的狀態(tài)
生命周期狀態(tài)為CREATED,表示onCreate()方法剛剛執(zhí)行完或者onStop()方法剛剛執(zhí)行完,也就是當(dāng)前activity不在前臺,但是也沒有處于銷毀狀態(tài)。
生命周期狀態(tài)為DESTORYED,表示當(dāng)前Activity還不存在,沒有被創(chuàng)建或者已經(jīng)銷毀,我們通??紤]比較多的就是,onDestory()方法執(zhí)行后,當(dāng)前Activity已經(jīng)銷毀。
所以,如果我們要保證在Activity或者Fragment的有效生命周期內(nèi)進(jìn)行的操作,必須判斷,當(dāng)前l(fā)ifecycle的狀態(tài)是否至少是CREATED狀態(tài),避免Activity或者fragment銷毀了以后,回調(diào)或者網(wǎng)絡(luò)請求才回來,此時(shí)做一些操作會導(dǎo)致異常。
添加以下代碼,就是我們把lifecycle對象傳給觀察者,讓它自己去判斷回調(diào)后的代碼,保證至少是CREATED狀態(tài)
private Lifecycle lifecycle;
public MyObserver(Lifecycle lifecycle) {
this.lifecycle = lifecycle;
}
//然后再相應(yīng)的回調(diào)方法中使用下面代碼判斷,保證數(shù)據(jù)回調(diào)回來,當(dāng)前activity是存在的
if (lifecycle.getCurrentState().isAtLeast(CREATED)) {
//這里只是示例,不一定是CREATED
}
這里用到了Lifecycle類的方法,下面我們看一下Lifecycle的源碼
public abstract class Lifecycle {
@MainThread //添加將在LifecycleOwner更改狀態(tài)時(shí)通知的LifecycleObserver。
public abstract void addObserver(@NonNull LifecycleObserver observer);
@MainThread //從觀察者列表中刪除給定的觀察者。
public abstract void removeObserver(@NonNull LifecycleObserver observer);
@MainThread //返回生命周期的當(dāng)前狀態(tài)。
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 //一個(gè)Event可以用來匹配所有事件的常數(shù)。
}
@SuppressWarnings("WeakerAccess")
public enum State {
DESTROYED,
INITIALIZED, //LifecycleOwner的初始化狀態(tài)。
CREATED,
STARTED,
RESUMED;
//比較此狀態(tài)是否大于或等于給定值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 {
}
就是一個(gè)抽象類,注釋已經(jīng)很詳細(xì)了,應(yīng)該不用解釋了
最后借用下官網(wǎng)的-生命周期感知組件的最佳實(shí)戰(zhàn)
- 盡可能保持您的UI控制器(活動和片段)盡可能精簡。他們不應(yīng)該試圖獲取他們自己的數(shù)據(jù);相反,使用ViewModel來做到這一點(diǎn),并觀察一個(gè)LiveData對象來反映更改回視圖。
- 嘗試編寫數(shù)據(jù)驅(qū)動的用戶界面,其中您的用戶界面控制器的職責(zé)是在數(shù)據(jù)更改時(shí)更新視圖,或?qū)⒂脩舨僮魍ㄖoViewModel。
- 把你的數(shù)據(jù)邏輯放在ViewModel類中。ViewModel應(yīng)作為您的UI控制器和其他應(yīng)用程序之間的連接器。但要小心,ViewModel不負(fù)責(zé)提取數(shù)據(jù)(例如,來自網(wǎng)絡(luò))。相反,ViewModel應(yīng)調(diào)用相應(yīng)的組件來獲取數(shù)據(jù),然后將結(jié)果提供給UI控制器。
- 使用dataBinding在視圖和UI控制器之間保持干凈的界面。這使您可以使您的視圖更具說明性,并最大限度地減少需要在活動和片段中編寫的更新代碼。
如果你喜歡用Java編程語言來做到這一點(diǎn),可以使用像Butter Knife這樣的庫來避免樣板代碼并且有更好的抽象。
- 如果您的UI很復(fù)雜,請考慮創(chuàng)建一個(gè)演示者類(presenter)來處理UI修改。這可能是一項(xiàng)艱巨的任務(wù),但它可以使您的UI組件更易于測試。
- 避免在ViewModel中引用View或Activity上下文。
如果ViewModel超出活動(在配置更改的情況下),則活動會泄漏并且垃圾收集器無法正確處理。
借用下https://blog.csdn.net/zhuzp_b... 作者的兩張圖,更清晰,對于相信信息,可到作者博客去查看相關(guān)講解

