Lifecycle介紹
相關(guān)類和接口
使用
實(shí)現(xiàn)原理
Lifecycle-生命周期感知組件
Lifecycle是Jetpack中提供的一個(gè)用于感知生命周期的組件,在應(yīng)用中主要用于監(jiān)聽 Activity
和Fragment
的生命周期變化型型,在合適的時(shí)候釋放資源庵芭,防止內(nèi)存泄露。使用Lifecycle可以將依賴組件的代碼從生命周期方法移入組件本身中涯曲。避免了直接在Activity
或Fragment
的生命周期方法中操作組件野哭。比如,我們常用的方式如下:
class MyActivity:AppCompatActivity() {
override fun onStart() {
super.onStart()
LocationUtils.start()
}
override fun onStop() {
super.onStop()
LocationUtils.stop()
}
}
如果多個(gè)頁面都用到了這個(gè)工具類幻件,就需要寫多遍拨黔,如果多人開發(fā),并不能保證一定都會(huì)調(diào)用對應(yīng)的方法绰沥。這樣難以維護(hù)篱蝇。
androidx.lifecycle
軟件包提供了可用于構(gòu)建生命周期感知組件的類和接口,這些組件可以根據(jù)Activity
或 Fragment
的當(dāng)前生命周期狀態(tài)自動(dòng)調(diào)整其行為徽曲。
相關(guān)類和接口
Lifecycle
Lifecycle
本身是一個(gè)抽象類旱易,用于存儲(chǔ)有關(guān)組件(如 Activity
或 Fragment
)的生命周期狀態(tài)的信息,并允許其他對象觀察此狀態(tài)管呵。它主要通過兩個(gè)枚舉類:Event和State來關(guān)聯(lián)組件的生命周期淮蜈。
LifecycleOwner
LifecycleOwner是一個(gè)接口,用于返回一個(gè)Lifecycle對象奥此,表示生命周期擁有者弧哎,提供者,屬于被觀察的對象稚虎。
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
LifecycleObserver
LifecycleObserver是一個(gè)標(biāo)記接口撤嫩,任何類都可以通過實(shí)現(xiàn)該接口來感知組件生命周期的變化,屬于觀察對象蠢终。
public interface LifecycleObserver {
}
實(shí)現(xiàn)
LifecycleObserver
的組件可與實(shí)現(xiàn)LifecycleOwner
的組件無縫協(xié)同工作序攘,因?yàn)樯芷谒姓呖梢?strong>提供生命周期鸭限,而觀察者可以注冊以觀察生命周期。
應(yīng)用
Activity和Fragment
在應(yīng)用中两踏,我們常用的就是監(jiān)聽Activity
和Fragment
的生命周期败京。Support Library 26.1.0及更高版本或AndroidX中的Fragment
和Activity
已實(shí)現(xiàn)了LifecycleOwner
接口。我們只需要將我們的工具類實(shí)現(xiàn)接口LifecycleObserver
來檢測或者感知Activity
和Fragment
的生命周期即可梦染。
- 1.通過向?qū)?yīng)的方法添加注解來監(jiān)控組件的生命周期狀態(tài)赡麦。
- 2.通過調(diào)用Lifecycle的
addObserver()
方法來添加觀察者
class LocationUtils(lifecycle: Lifecycle) : LifecycleObserver {
init {
//添加觀察者
lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun start() {
TODO()
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stop() {
TODO()
}
}
//使用,創(chuàng)建對象后帕识,在需要使用的地方直接調(diào)用對應(yīng)的功能即可泛粹,不需要再外面關(guān)聯(lián)組件的生命周期。
val location = LocationUtils(lifecycle)
如果我們需要從另一個(gè)
Activity
或Fragment
使用LocationUtils肮疗,只需對其進(jìn)行初始化晶姊。所有設(shè)置和拆解操作都由類本身管理。 這樣還有一個(gè)好處就是:如果start()
改成在onResume()
中調(diào)用伪货,不需要更改調(diào)用的地方们衙,只需要更改定義的地方。這樣維護(hù)成本低碱呼。
自定義 LifecycleOwner
如果想把我們自定義的類變成為LifecycleOwner
蒙挑,就需要借助LifecycleRegistry
將事件轉(zhuǎn)發(fā)到該類,如下代碼所示:
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry lifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry = new LifecycleRegistry(this);
lifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void onStart() {
super.onStart();
lifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
}
使用生命周期感知組件可以很方便地管理生命周期:
- 在粗粒度和細(xì)粒度位置更新之間切換愚臀。
- 停止和開始視頻緩沖忆蚀。
- 開始和停止網(wǎng)絡(luò)連接。
暫停和恢復(fù)動(dòng)畫姑裂。
如果Lifecycle
的實(shí)現(xiàn)是AppCompatActivity
或Fragment
馋袜,那么當(dāng)調(diào)用它們的onSaveInstanceState()
方法時(shí),Lifecycle
的狀態(tài)會(huì)更改為CREATED并且會(huì)分派ON_STOP事件舶斧。
實(shí)現(xiàn)原理
簡單來說:就是通過一個(gè)無頁面的Fragment欣鳖。通過在對指定Activity
注冊無頁面的Fragment
,傳遞頁面Activity生命周期到Fragment
捧毛。然后通過Fragment
綁定LifecycleRegistry观堂,當(dāng)Fragment
的生命周期變化時(shí)让网,回調(diào)LifecycleRegistry中LifecycleObserver
對象相應(yīng)的生命周期回調(diào)方法呀忧。
我們觀察Activity
的生命周期,只要是通過下述代碼:
lifecycle.addObserver(this)
就以此為入口溃睹,看一下它的實(shí)現(xiàn):getLifecycle()
方法返回的是ComponentActivity中的mLifecycleRegistry
而账,如果你用的是support包,它定義SupportActivity中因篇,我這里使用的AndroidX泞辐。
public class ComponentActivity extends androidx.core.app.ComponentActivity implements ...{
...
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
...
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
...
}
我們調(diào)用的addObserver()
方法笔横,實(shí)際上調(diào)用的就是LifecycleRegistry里面的:
public class LifecycleRegistry extends Lifecycle {
...
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//將傳進(jìn)來的observer包裝成一個(gè)ObserverWithState,并放入集合中
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
...
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
//分發(fā)事件
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
targetState = calculateTargetState(observer);
}
...
}
...
}
從上面可以看出有一個(gè)while循環(huán)
咐吼,條件是比較觀察者和被觀察者的State的序數(shù)吹缔, DESTROYED、INITIALIZED锯茄、CREATED厢塘、STARTED和RESUMED
的序數(shù)依次為0,1,2,3,4。狀態(tài)變化后肌幽,在該循環(huán)體中晚碾,調(diào)用了statefulObserver.dispatchEvent()
方法,分發(fā)事件喂急。該方法的具體實(shí)現(xiàn)如下:
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
在ObserverWithState創(chuàng)建的時(shí)候?qū)魅氲?code>observer解析并返回接口LifecycleEventObserver實(shí)現(xiàn)類的對象格嘁,最后調(diào)用它的onStateChanged()
方法。我們在使用Lifecycle的時(shí)候使用的是注解的方式:@onLifecycleEvent廊移,那么注解處理器會(huì)將該注解解析并動(dòng)態(tài)生成GeneratedAdapte
代碼糕簿,這個(gè)GeneratedAdapter
會(huì)把對應(yīng)的Lifecycle.Event封裝為方法調(diào)用。最終通過GenericLifecycleObserve的onStateChanged
方法調(diào)用生成的GeneratedAdapter的callMechods()
方法進(jìn)行事件分發(fā)狡孔。
public class LocationUtils_LifecycleAdapter implements GeneratedAdapter {
final LocationUtils mReceiver;
LocationUtils_LifecycleAdapter(LocationUtils receiver) {
this.mReceiver = receiver;
}
@Override
public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,MethodCallsLogger logger) {
boolean hasLogger = logger != null;
if (onAny) {
return;
}
if (event == Lifecycle.Event.ON_START) {
if (!hasLogger || logger.approveCall("start", 1)) {
mReceiver.start();
}
return;
}
if (event == Lifecycle.Event.ON_STOP) {
if (!hasLogger || logger.approveCall("stop", 1)) {
mReceiver.stop();
}
return;
}
}
}
上面這個(gè)就是狀態(tài)變化時(shí)事件分發(fā)的基本流程冶伞,那么它是如何感知生命周期狀態(tài)變化的呢?我們調(diào)用Lifecycle的addObserver()
方法步氏,實(shí)際調(diào)用的是ComponentActivity中mLifecycleRegistry對象的方法响禽,而我們關(guān)注Activity的生命周期是從onCreate()
開始,所以下面看一下ComponentActivity的onCreate()
方法:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
在onCreate()
方法中調(diào)用了ReportFragment的injectIfNeedIn()
方法荚醒。這個(gè)方法其實(shí)就是往Activity中添加了一個(gè)Fragment芋类。而Fragment是依附于Activity的,所以Fragment的生命周期會(huì)跟隨Activity的生命周期界阁。既然ReportFragment能感知Activity的生命周期侯繁,那么它是如何改變狀態(tài)的?
public class ReportFragment extends Fragment {
...
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
...
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onStop() {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
}
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
mProcessListener = null;
}
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
...
}
從上面可以看出泡躯,在ReportFragment對應(yīng)的生命周期方法中會(huì)調(diào)用dispatch()
方法贮竟,并傳遞對應(yīng)的事件Lifecycle.Event.XXX,而dispatch()
方法中則是調(diào)用了LifecycleRegistry的handleLifecycleEvent()
方法。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
//狀態(tài)的變化轉(zhuǎn)化為生命周期事件较剃,然后轉(zhuǎn)發(fā)給 LifecycleObserver
sync();
mHandlingEvent = false;
}
一圖勝千語咕别,下面用一張圖來總結(jié)大致的流程: