1、概述
google的jetpack已經出來很久了,最近項目中用接入后,也是遇到了不少坑。于是抽時間好好研究了下lifecycle、livedata、viewModel等源碼,本文就來介紹一下lifecycle的用法及原理。
2、設計初衷
先來一句官方解釋:android.arch.lifecycle 包提供了可以用于構建生命周期感知(lifecycle-aware)組件的類和接口,這些組件可以根據 Activity 或 Fragment 的當前生命周期自動調整其行為。
我的理解就是你可以用lifecycle使任何一個類具有生命周期。這個生命周期會跟隨activity或fragment的生命周期。(其實并不一定要activity,只要實現lifecycleOwner既可,這個后面再說)
掏出一個官方的例子:
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// 鏈接到系統定位服務
}
void stop() {
// 斷開系統定位服務
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
}
public void onStart() {
super.onStart();
myLocationListener.start();
}
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
我們以前代碼里常常出現類似這樣的場景,看似沒啥毛病,但很多這樣的Listener會導致onstop之類的生命周期看起來臃腫,而且自己寫起來也麻煩,于是lifecycle孕育而生。
3、基本使用
使用的話,總結為一句話:需要一個LifecycleOwner,和一個LifecycleObserver,然后觀察起來就好了,這樣LifecycleObserver就會跟隨LifecycleOwner的生命周期了。所以上面的例子里MyActivity就是LifecycleOwner,MyLocationListener就是LifecycleObserver。用代碼來表示就像這樣:
class MyLocationListener implements LifecycleObserver {
public MyLocationListener(Context context, Callback callback) {
// ...
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
// 鏈接到系統定位服務
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void stop() {
// 斷開系統定位服務
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
getLifecycle().addObserver(myLocationListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
getLifecycle().removeObserver(myLocationListener);
}
}
其中AppCompatActivity已經實現了LifecycleOwner,無需我們自己操作。就像我上面說的一樣,重點在于這一句:getLifecycle().addObserver(myLocationListener);
而實現LifecycleObserver的需要將自己的生命周期方法加上注釋@OnLifecycleEvent。用法很簡單,大致就是這樣。這個方式主要用于你希望賦予某個類生命周期。比如MVP模式的presenter、MVVM模式的ViewModel,擁有生命周期后就可以在其中做一些釋放內存之類的操作。
4、原理解析
注意是原理,而不是源碼,受到某些影響,現在不喜歡大段大段貼源碼的方式寫作,感覺不僅難以理解還無法理解其思想。
lifecycle很明顯是基于觀察者模式,被觀察者為LifecycleOwner,他只有一個方法:getLifecycle(); 具體實現,我們就挑google現成的例子:fragment。
fragment關于lifecycle的代碼抽出來很簡單:
public class Fragment implements xxx, LifecycleOwner {
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
//...
void performCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performStart() {
onStart();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
void performResume() {
onResume();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
void performPause() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
onPause();
}
void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
onStop();
}
void performDestroy() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
onDestroy();
}
}
很明顯,真正作為lifecycle的是LifecycleRegistry,fragment僅僅是將生命周期進行分發。而LifecycleRegistry確實是實現了Lifecycle,看看Lifecycle的設計:
public abstract class Lifecycle {
public abstract void addObserver(@NonNull LifecycleObserver observer);
public abstract void removeObserver(@NonNull LifecycleObserver observer);
public abstract State getCurrentState();
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
看起來也非常簡潔,添加觀察者、移除觀察者、當前狀態,以及event和state的設計。LifecycleRegistry實現了該接口,完成了觀察者具體實現,這里就不詳細解析了,可以自行學習源碼。簡單來說就是通過添加觀察者,當生命周期改變時調用handleLifecycleEvent方法通知LifecycleObserver,并調用相關方法。
LifecycleObserver
接下來聊聊這個LifecycleObserver,google提供的實現方案有兩種,在lifecycle類的注釋上寫的很清楚,
其一是和我們上面的實現方案:實現LifecycleObserver接口,在相關生命周期方法上加上OnLifecycleEvent注釋,這種方案適用于JAVA7及以下,會根據注釋利用APT編譯期自動生成GeneratedAdapter實現類,只有一個方法callMethods,當生命周期改變時會回調該方法,并在該方法內回調我們注釋過的相應的生命周期。底層還是利用GenericLifecycleObserver來實現的,這個我們后面再解析。
其二是實現DefaultLifecycleObserver,里面有相關的生命周期方法。適用于JAVA8以上,google推薦使用該類方案,因為當JAVA8成為Android主流后可能第一種方案就會被遺棄。
無論傳入的是哪一種Observer,都會被包裝成對應的Observer,關鍵代碼在LifecycleRegistry的內部包裝類ObserverWithState中
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//這里包裝observer
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
//包裝成GenericLifecycleObserver,生命周期改變時調用
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
}
我們來看看Lifecycling.getCallback(observer)是如何包裝的:
@NonNull
static GenericLifecycleObserver getCallback(Object object) {
//第二種方案走這里,DefaultLifecycleObserver繼承于FullLifecycleObserver
if (object instanceof FullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
}
//livedata的生命周期走這里,后面詳解
if (object instanceof GenericLifecycleObserver) {
return (GenericLifecycleObserver) object;
}
//第一種方案走這里,通過apt方式生成的adapter類
final Class<?> klass = object.getClass();
int type = getObserverConstructorType(klass);
if (type == GENERATED_CALLBACK) {
List<Constructor<? extends GeneratedAdapter>> constructors =
sClassToAdapters.get(klass);
if (constructors.size() == 1) {
GeneratedAdapter generatedAdapter = createGeneratedAdapter(
constructors.get(0), object);
return new SingleGeneratedAdapterObserver(generatedAdapter);
}
GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
for (int i = 0; i < constructors.size(); i++) {
adapters[i] = createGeneratedAdapter(constructors.get(i), object);
}
return new CompositeGeneratedAdaptersObserver(adapters);
}
return new ReflectiveGenericLifecycleObserver(object);
}
無論是哪一種方案,哪一種observer,都會去實現onStateChanged方法,我們拿第二種方案為例,看看FullLifecycleObserverAdapter中的實現:
class FullLifecycleObserverAdapter implements GenericLifecycleObserver {
private final FullLifecycleObserver mObserver;
FullLifecycleObserverAdapter(FullLifecycleObserver observer) {
mObserver = observer;
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
switch (event) {
case ON_CREATE:
mObserver.onCreate(source);
break;
case ON_START:
mObserver.onStart(source);
break;
case ON_RESUME:
mObserver.onResume(source);
break;
case ON_PAUSE:
mObserver.onPause(source);
break;
case ON_STOP:
mObserver.onStop(source);
break;
case ON_DESTROY:
mObserver.onDestroy(source);
break;
case ON_ANY:
throw new IllegalArgumentException("ON_ANY must not been send by anybody");
}
}
}
很明顯,當onStateChanged被調用時,根據event回調我們實現的DefaultLifecycleObserver里的各種生命周期方法。其他方案類似,就不一一列出了。
理一下思路:
1、在LifecycleOwner中加入各種類型的observer觀察者,LifecycleOwner真正實現是LifecycleRegistry。
2、在LifecycleRegistry中利用Lifecycling包裝observer為GenericLifecycleObserver
3、調用GenericLifecycleObserver的onStateChanged方法進行event分發,這里有策略模式的影子
5、自定義LifecycleOwner
根據上一節原理以及google對fragment的實現,自定義LifecycleOwner就很簡單了。總結為兩句話:1、生成一個LifecycleRegistry。2、分發生命周期事件
加入我們要把dialog變成LifecycleOwner,就像這樣:
public class baseDialog extends Dialog implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Bundle onSaveInstanceState() {
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
return super.onSaveInstanceState();
}
//...省略了其他生命周期
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
@Override
protected void onStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
super.onStop();
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
6、LiveData的生命周期管理
LiveData是jetpack另外一個重要的組件,用于監聽數據變更,UI做出相應響應,這里就不詳細介紹了,他也是基于觀察者模式,自然需要解綁避免內存泄漏。但他內部已經處理好生命周期,我們只管使用無須擔心。自然,他就是用lifecycle來實現的。
我們前面提到lifecycle是賦予某個類生命周期才出現的,LiveData雖然無需那么多生命周期,但是可以利用他在LifecycleOwner(Activity...)ondestroy時同步解綁,就完成了LiveData的自動釋放。
LiveData自己實現了observer:LifecycleBoundObserver,然后在onStateChanged方法里判斷是否需要解綁即可。
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//判斷如果狀態是DESTROYED就解綁
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
LiveData的源碼也很簡單,只有不到500行代碼,還有不少一部分是注釋,感興趣可以自行閱讀。