本系列博客基于androidx-2.2.0版本
【JetPack系列】——Lifecycle源碼分析
【JetPack系列】——LiveData源碼解析
【JetPack系列】——ViewModel源碼解析
前言
Google的JetPack組件已經(jīng)出了一段時間了,正如Google說明的那樣,利用這套框架可以很便捷的幫助開發(fā)者快速的迭代開發(fā),這應(yīng)該是Google官方推出的較為正規(guī)的一套框架了,無論從設(shè)計還是目前的應(yīng)用推廣程度,都是目前Android開發(fā)者需要掌握的一套框架。本系列主要分析JetPack的三個框架:Lifecycle、LiveData、ViewModel。
本篇博客主要分析我認(rèn)為是三個組件的根基Lifecycle,正是Lifecycle的出現(xiàn),為后面的很多框架提供了感知生命周期的基礎(chǔ)能力。
首先對于Lifecycle我們應(yīng)該有一個基礎(chǔ)的認(rèn)知,這個框架是干什么的。這里放上Google官方介紹的地地址。簡單的說Lifecycle是一個用于賦予組件感知生命周期能力的框架,看到這里我們對于這個框架的第一個想法應(yīng)該是觀察者者模式,沒錯,因為無論框架用到了什么高大上的技術(shù),最基礎(chǔ)的原理肯定是感知Activity的生命周期,然后通過注冊觀察者分發(fā)下去,至于里面用到了一些看似高科技的技術(shù),只是一個框架從設(shè)計角度來簡便使用者的使用成本,所以至此,我們第一步先對Lifecycle有了一個基礎(chǔ)的認(rèn)知。
源碼分析
既然前面提到了觀察者模式,那么我們閱讀源碼的思路就很清晰了,我們這里分為兩個部分:1.觀察者2.被觀察者。
被觀察者-LifecycleOwner
public interface LifecycleOwner {
Lifecycle getLifecycle();
}
我們來看下被觀察者的接口,很簡單,沒有過多復(fù)雜的方法,那么既然是被觀察者,能體現(xiàn)生命周期的肯定脫離不了Activity、Fragment這兩者,所以我們看下這個接口的實現(xiàn)類,果然找到了和Activity相關(guān)的身影-SupportActivity
public class SupportActivity extends Activity implements LifecycleOwner {
private SimpleArrayMap<Class<? extends SupportActivity.ExtraData>, SupportActivity.ExtraData> mExtraDataMap = new SimpleArrayMap();
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
public SupportActivity() {
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
public Lifecycle getLifecycle() {
return this.mLifecycleRegistry;
}
}
這里簡化了下代碼,可以看到兩個核心的地方,一個是重寫了getLifecycle()方法,可以看到Lifecycle的實現(xiàn)類LifecycleRegistry,一個是ReportFragment.injectIfNeededIn(this);
public static void injectIfNeededIn(Activity activity) {
FragmentManager manager = activity.getFragmentManager();
if(manager.findFragmentByTag("android.arch.lifecycle.LifecycleDispatcher.report_fragment_tag") == null) {
manager.beginTransaction().add(new ReportFragment(), "android.arch.lifecycle.LifecycleDispatcher.report_fragment_tag").commit();
manager.executePendingTransactions();
}
}
首先看下injectIfNeededIn方法,這里可以看到這個方法就是一個向Activity注入Fragment的方法,看到這里如果我們看過Glide的源碼或者了解過Glide的原理的,我們應(yīng)該會聯(lián)想到這里的Fragment的作用會不會是一個空的Fragment用于感知生命周期的。
public class ReportFragment extends Fragment {
private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle.LifecycleDispatcher.report_fragment_tag";
private ReportFragment.ActivityInitializationListener mProcessListener;
public ReportFragment() {
}
static ReportFragment get(Activity activity) {
return (ReportFragment)activity.getFragmentManager().findFragmentByTag("android.arch.lifecycle.LifecycleDispatcher.report_fragment_tag");
}
private void dispatchCreate(ReportFragment.ActivityInitializationListener listener) {
if(listener != null) {
listener.onCreate();
}
}
private void dispatchStart(ReportFragment.ActivityInitializationListener listener) {
if(listener != null) {
listener.onStart();
}
}
private void dispatchResume(ReportFragment.ActivityInitializationListener listener) {
if(listener != null) {
listener.onResume();
}
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.dispatchCreate(this.mProcessListener);
this.dispatch(Event.ON_CREATE);
}
public void onStart() {
super.onStart();
this.dispatchStart(this.mProcessListener);
this.dispatch(Event.ON_START);
}
public void onResume() {
super.onResume();
this.dispatchResume(this.mProcessListener);
this.dispatch(Event.ON_RESUME);
}
public void onPause() {
super.onPause();
this.dispatch(Event.ON_PAUSE);
}
public void onStop() {
super.onStop();
this.dispatch(Event.ON_STOP);
}
public void onDestroy() {
super.onDestroy();
this.dispatch(Event.ON_DESTROY);
this.mProcessListener = null;
}
private void dispatch(Event event) {
Activity activity = this.getActivity();
if(activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner)activity).getLifecycle().handleLifecycleEvent(event);
} else {
if(activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner)activity).getLifecycle();
if(lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry)lifecycle).handleLifecycleEvent(event);
}
}
}
}
void setProcessListener(ReportFragment.ActivityInitializationListener processListener) {
this.mProcessListener = processListener;
}
interface ActivityInitializationListener {
void onCreate();
void onStart();
void onResume();
}
}
這里放上了源碼,果然和我們想的一樣,這里其實就是一個空的Fragment,用于感知生命周期,然后子在dispatch方法里分發(fā),因為LifecycleRegistryOwner已經(jīng)是一個過時的類了,所以這里就不做分析,剛才我們也看到了我們的SupportActivity是實現(xiàn)了LifecycleOwner接口,所以這里可以看到就會調(diào)用LifecycleRegistry的handlerLifecycleEvent方法。
所以這里我們可以得出一個結(jié)論:被觀察者通過注入一個空的Fragment來感知生命周期并分發(fā)
但我們這里可能會有一個疑問,如果我們沒有繼承這個SupportActivity怎么辦。我們可以看下調(diào)用injectIfNeededIn方法的地方,會發(fā)現(xiàn)除了SupportActivity還會有一個地方調(diào)用LifecycleDispatcher
class LifecycleDispatcher {
private static AtomicBoolean sInitialized = new AtomicBoolean(false);
static void init(Context context) {
if (sInitialized.getAndSet(true)) {
return;
}
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.injectIfNeededIn(activity);
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
}
private LifecycleDispatcher() {
}
}
這樣就比較清晰了,可以看到其實通過Application的registerActivityLifecycleCallbacks方法,來向Activity中注入Fragment。這里有個比較奇妙的地方,可以看下調(diào)用init方法的地方。
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
}
會發(fā)現(xiàn),Google其實用一個ContentProvider來實習(xí)無痕初始化這里特意提下ContentProvider的特性,我們只需要在AndroidManifest.xml文件中配置一下ContentProvider的信息,就不需要在Application或其他地方做初始化的操作,ContentProvider會在Application初始化前自動就加載進(jìn)來,具體就不在這里展開說明了。(其實LeakCanary2也是利用這個特性來完成的無痕初始化)
觀察者-LifecycleObserver
public interface LifecycleObserver {
}
可以看到觀察者其實是一個空接口,但其實有很多對應(yīng)的實現(xiàn)接口例如:
interface FullLifecycleObserver extends LifecycleObserver {
void onCreate(LifecycleOwner owner);
void onStart(LifecycleOwner owner);
void onResume(LifecycleOwner owner);
void onPause(LifecycleOwner owner);
void onStop(LifecycleOwner owner);
void onDestroy(LifecycleOwner owner);
}
public interface LifecycleEventObserver extends LifecycleObserver {
/**
* Called when a state transition event happens.
*
* @param source The source of the event
* @param event The event
*/
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
也就是我們可以實現(xiàn)不同的接口,來實現(xiàn)我們感應(yīng)生命周期的需求。
但其實我對于這的設(shè)計是感覺有一些不妥的,Google在這里提供了豐富的接口,來對應(yīng)我們使用不同的需求,但是這也給這套框架本身帶來了很大的不便,后面的分析可以看到Lifecycle需要對應(yīng)每一個接口做一個adapter適配,最終適配為一種類型,這個無疑增加了開發(fā)成本和理解成本,并且從設(shè)計來說,以一個空接口作為判斷的依據(jù),我認(rèn)為是有一些不妥的,雖然對于使用者的出發(fā)點是好的,但是也一方面增加了使用者的學(xué)習(xí)成本,
注冊觀察者-addObserver
public void addObserver(LifecycleObserver observer) {
State initialState = this.mState == State.DESTROYED?State.DESTROYED:State.INITIALIZED;
//1.包裝適配不同的接口類型
LifecycleRegistry.ObserverWithState statefulObserver = new LifecycleRegistry.ObserverWithState(observer, initialState);
//2.增加觀察者
LifecycleRegistry.ObserverWithState previous = (LifecycleRegistry.ObserverWithState)this.mObserverMap.putIfAbsent(observer, statefulObserver);
if(previous == null) {
boolean isReentrance = this.mAddingObserverCounter != 0 || this.mHandlingEvent;
//3.粘性事件,保持生命周期一致
State targetState = this.calculateTargetState(observer);
++this.mAddingObserverCounter;
while(statefulObserver.mState.compareTo(targetState) < 0 && this.mObserverMap.contains(observer)) {
this.pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(this.mLifecycleOwner, upEvent(statefulObserver.mState));
this.popParentState();
targetState = this.calculateTargetState(observer);
}
if(!isReentrance) {
///4.分發(fā)
this.sync();
}
--this.mAddingObserverCounter;
}
}
這個其實是我將觀察分為了四個步驟:
- 1.包裝適配不同的接口類型
- 2.增加觀察者
- 3.粘性事件,保持生命周期的一致
- 4.分發(fā)
所以這里我們也分為了四個小塊來看一下
包裝適配不同的接口類型
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//傳入的LifecycleObserver轉(zhuǎn)換成了GenericLifecycleObserver
this.mLifecycleObserver = Lifecycling.getCallback(observer);
this.mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = LifecycleRegistry.getStateAfter(event);
this.mState = LifecycleRegistry.min(this.mState, newState);
this.mLifecycleObserver.onStateChanged(owner, event);
this.mState = newState;
}
}
這里其實最核心的步驟就是拿ObserverWithState將我們傳入的LifecycleObserver包裝起來,轉(zhuǎn)換成GenericLifecycleObserver。核心的轉(zhuǎn)化方法就是在Lifecycling.getCallback(observer);中。
@NonNull
static GenericLifecycleObserver getCallback(Object object) {
//實現(xiàn)了FullLifecycleObserver接口
if (object instanceof FullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
}
//實現(xiàn)了GenericLifecycleObserver接口
if (object instanceof GenericLifecycleObserver) {
return (GenericLifecycleObserver) object;
}
//使用了注解,這里分為編譯期注解和運行時注解
final Class<?> klass = object.getClass();
int type = getObserverConstructorType(klass);
// 獲取 type
// GENERATED_CALLBACK 表示注解生成的代碼
// REFLECTIVE_CALLBACK 表示使用反射
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);
}
其實可以看到就是那一個包裝類將我們傳入的類型轉(zhuǎn)換成了GenericLifecycleObserver類型,這里主要看下如何區(qū)分編譯期注解和運行時注解的,首先說明下兩個區(qū)別
1.編譯期注解:其實了解AOP的應(yīng)該都知道現(xiàn)在有很多注解作用于編譯期,在編譯的過程中,通過識別注解,來插入對應(yīng)的代碼或者生成對應(yīng)的代碼,
2.運行時注解:其實就是反射,通過反射來找到對應(yīng)的注解的內(nèi)容,來執(zhí)行對應(yīng)的操作,反射需要注意混淆帶來的影響。
private static int getObserverConstructorType(Class<?> klass) {
//這里有一個緩存,增加效率
if (sCallbackCache.containsKey(klass)) {
return sCallbackCache.get(klass);
}
int type = resolveObserverCallbackType(klass);
sCallbackCache.put(klass, type);
return type;
}
private static int resolveObserverCallbackType(Class<?> klass) {
// anonymous class bug:35073837
// 匿名內(nèi)部類使用反射
if (klass.getCanonicalName() == null) {
return REFLECTIVE_CALLBACK;
}
// 尋找注解生成的 GeneratedAdapter 類
Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass);
if (constructor != null) {
sClassToAdapters.put(klass, Collections
.<Constructor<? extends GeneratedAdapter>>singletonList(constructor));
return GENERATED_CALLBACK;
}
// 尋找被 OnLifecycleEvent 注解的方法
boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
if (hasLifecycleMethods) {
return REFLECTIVE_CALLBACK;
}
// 沒有找到注解生成的 GeneratedAdapter 類,也沒有找到 OnLifecycleEvent 注解,
// 則向上尋找父類
Class<?> superclass = klass.getSuperclass();
List<Constructor<? extends GeneratedAdapter>> adapterConstructors = null;
if (isLifecycleParent(superclass)) {
if (getObserverConstructorType(superclass) == REFLECTIVE_CALLBACK) {
return REFLECTIVE_CALLBACK;
}
adapterConstructors = new ArrayList<>(sClassToAdapters.get(superclass));
}
// 尋找是否有接口實現(xiàn)
for (Class<?> intrface : klass.getInterfaces()) {
if (!isLifecycleParent(intrface)) {
continue;
}
if (getObserverConstructorType(intrface) == REFLECTIVE_CALLBACK) {
return REFLECTIVE_CALLBACK;
}
if (adapterConstructors == null) {
adapterConstructors = new ArrayList<>();
}
adapterConstructors.addAll(sClassToAdapters.get(intrface));
}
if (adapterConstructors != null) {
sClassToAdapters.put(klass, adapterConstructors);
return GENERATED_CALLBACK;
}
return REFLECTIVE_CALLBACK;
}
這里面的方法就不在這里展開了,單獨看一下如何找到編譯期的類吧,其他的其實都是反射的常用操作,找父類是否實現(xiàn),找注解方法,遍歷接口的方法,沒有復(fù)雜的代碼。
@Nullable
private static Constructor<? extends GeneratedAdapter> generatedConstructor(Class<?> klass) {
try {
Package aPackage = klass.getPackage();
String name = klass.getCanonicalName();
final String fullPackage = aPackage != null ? aPackage.getName() : "";
final String adapterName = getAdapterName(fullPackage.isEmpty() ? name :
name.substring(fullPackage.length() + 1));
@SuppressWarnings("unchecked") final Class<? extends GeneratedAdapter> aClass =
(Class<? extends GeneratedAdapter>) Class.forName(
fullPackage.isEmpty() ? adapterName : fullPackage + "." + adapterName);
Constructor<? extends GeneratedAdapter> constructor =
aClass.getDeclaredConstructor(klass);
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
return constructor;
} catch (ClassNotFoundException e) {
return null;
} catch (NoSuchMethodException e) {
// this should not happen
throw new RuntimeException(e);
}
}
/**
* Create a name for an adapter class.
*/
public static String getAdapterName(String className) {
return className.replace(".", "_") + "_LifecycleAdapter";
}
這里可以看到其實這里也是用反射去找類,并且通過Class.forName去加載類,然后通過反射來得到構(gòu)造函數(shù)。這里比較有趣的是這里獲取類名的時候,其實是用字符串拼接LifecycleAdapter,如果使用過Lifecycle的注解的應(yīng)該會發(fā)現(xiàn),當(dāng)你使用一個注解后,在編譯期通過后,會自動生成一個xxxx_LifecycleAdapter類。
@Generated("androidx.lifecycle.LifecycleProcessor")
public class ObserverNoAdapter_LifecycleAdapter implements GeneratedAdapter {
final ObserverNoAdapter mReceiver;
ObserverNoAdapter_LifecycleAdapter(ObserverNoAdapter 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_STOP) {
if (!hasLogger || logger.approveCall("doOnStop", 1)) {
mReceiver.doOnStop();
}
return;
}
}
}
可以看懂,其實和上面的類沒有太大的區(qū)別,只不過就是通過編譯期注解來生成的,然后通過Class.forName來獲取。
至此,我們第一小步已經(jīng)分析完成了,我們可以總結(jié)下:
1.我們傳入的
LifecycleObserver會被轉(zhuǎn)換成GenericLifecycleObserver
2.轉(zhuǎn)換的方式根據(jù)我們的實現(xiàn)方式不同對應(yīng)不同,其中要注意的是編譯期注解是在編譯時生成的LifecycleAdapter結(jié)尾的包裝類
3.我還是覺得Google這樣有點秀操作的意思,維護和學(xué)習(xí)成本變高了
2.增加觀察者
LifecycleRegistry.ObserverWithState previous = (LifecycleRegistry.ObserverWithState)this.mObserverMap.putIfAbsent(observer, statefulObserver);
這里看似簡單,起初我也是感覺沒有什么好分析的,但是有一次,我在使用Map的過程中,循環(huán)中使用remove導(dǎo)致ConcurrentModificationException,這個地方引起了我的注意,我們在使用Lifecycle的時候,如果在生命周期內(nèi)移除了Observer,是不會出現(xiàn)異常的,這一點就引起了我的興趣。最后我發(fā)現(xiàn)這歸功于這里特殊的Map結(jié)構(gòu),所以我們這里來看一下使用的Map結(jié)構(gòu)吧。
/**
* Poor's man LinkedHashMap, which supports modifications during iterations.
* Takes more memory that {@link SafeIterableMap}
* It is NOT thread safe.
*
* @param <K> Key type
* @param <V> Value type
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
public class FastSafeIterableMap<K, V> extends SafeIterableMap<K, V> {
private HashMap<K, Entry<K, V>> mHashMap = new HashMap<>();
@Override
protected Entry<K, V> get(K k) {
return mHashMap.get(k);
}
@Override
public V putIfAbsent(@NonNull K key, @NonNull V v) {
Entry<K, V> current = get(key);
if (current != null) {
return current.mValue;
}
mHashMap.put(key, put(key, v));
return null;
}
@Override
public V remove(@NonNull K key) {
V removed = super.remove(key);
mHashMap.remove(key);
return removed;
}
/**
* Returns {@code true} if this map contains a mapping for the specified
* key.
*/
public boolean contains(K key) {
return mHashMap.containsKey(key);
}
/**
* Return an entry added to prior to an entry associated with the given key.
*
* @param k the key
*/
public Map.Entry<K, V> ceil(K k) {
if (contains(k)) {
return mHashMap.get(k).mPrevious;
}
return null;
}
}
這里首先看下名字,就很有意思FastSafeIterableMap,直譯過來就是又快又安全,在看下注釋
/**
* Poor's man LinkedHashMap, which supports modifications during iterations.
* Takes more memory that {@link SafeIterableMap}
* It is NOT thread safe
* 低配版的LinkedHashMap,支持循環(huán)的時候修改內(nèi)容,比SafeIterableMap更耗費內(nèi)存,不是線程安全的。
**/
所以我們通過注釋可以了解到這個是一個支持在循環(huán)的時候修改內(nèi)容的Map,這個其實就很好,而我們在看下到底是如何實現(xiàn)這樣的功能,我們看下這個類的父類。
public class SafeIterableMap<K, V> implements Iterable<Map.Entry<K, V>> {
@SuppressWarnings("WeakerAccess") /* synthetic access */
Entry<K, V> mStart;
private Entry<K, V> mEnd;
// using WeakHashMap over List<WeakReference>, so we don't have to manually remove
// WeakReferences that have null in them.
private WeakHashMap<SupportRemove<K, V>, Boolean> mIterators = new WeakHashMap<>();
private int mSize = 0;
/**
* Removes the mapping for a key from this map if it is present.
*
* @param key key whose mapping is to be removed from the map
* @return the previous value associated with the specified key,
* or {@code null} if there was no mapping for the key
*/
public V remove(@NonNull K key) {
Entry<K, V> toRemove = get(key);
if (toRemove == null) {
return null;
}
mSize--;
if (!mIterators.isEmpty()) {
for (SupportRemove<K, V> iter : mIterators.keySet()) {
iter.supportRemove(toRemove);
}
}
if (toRemove.mPrevious != null) {
toRemove.mPrevious.mNext = toRemove.mNext;
} else {
mStart = toRemove.mNext;
}
if (toRemove.mNext != null) {
toRemove.mNext.mPrevious = toRemove.mPrevious;
} else {
mEnd = toRemove.mPrevious;
}
toRemove.mNext = null;
toRemove.mPrevious = null;
return toRemove.mValue;
}
}
具體這里就不全部放出來了,這里自看下核心的關(guān)鍵的地方,可以看到這里其實是一個用一個鏈表的結(jié)構(gòu),而我們的remove也會對應(yīng)的修改鏈表的指針,在使用游標(biāo)遍歷的時候,也沒有做關(guān)于ConcurrentModificationException的檢測,這個Map的實現(xiàn)還是很值得我們學(xué)習(xí)的,但是這里要吐槽下,為啥Google不把這個類開放出來,這個類其實是一個包私有的類,也是我們平時的開發(fā)無法使用的,可能也是考慮性能的因素,而且和正常的數(shù)據(jù)結(jié)構(gòu)還是有差異的。
粘性事件,保持生命周期一致
State targetState = this.calculateTargetState(observer);
++this.mAddingObserverCounter;
while(statefulObserver.mState.compareTo(targetState) < 0 && this.mObserverMap.contains(observer)) {
this.pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(this.mLifecycleOwner, upEvent(statefulObserver.mState));
this.popParentState();
targetState = this.calculateTargetState(observer);
}
這一步我個人感覺其實是Lifecycle和LiveData的核心思想,這里首先提一問題:
如果在onResumed的時候注冊了Observer,那么我們的Observer的生命周期會如何回調(diào)
這里就不得不吹一波Google的設(shè)計了,如果交給我們設(shè)計一款生命周期感知的組件,我們可能就是基礎(chǔ)的觀察者模式,然后再對應(yīng)的生命周期,利用遍歷,通知觀察者就可以了。但是Google在這里的考慮了兩個概念,一個是倒灌(我個人比較喜歡稱粘性),一個是重入,現(xiàn)在說這兩個概念可能會讓人有點困擾,所以我們先一步一步分析,后面再圍繞兩個概念展開。
private State calculateTargetState(LifecycleObserver observer) {
//之前的觀察者的生命周期
Entry<LifecycleObserver, LifecycleRegistry.ObserverWithState> previous = this.mObserverMap.ceil(observer);
State siblingState = previous != null?((LifecycleRegistry.ObserverWithState)previous.getValue()).mState:null;
State parentState = !this.mParentStates.isEmpty()?(State)
//和重入概念有關(guān),常規(guī)情況為null
this.mParentStates.get(this.mParentStates.size() - 1):null;
、、比較當(dāng)前state和之前的觀察者的狀態(tài)的最小者
return min(min(this.mState, siblingState), parentState);
}
這里做了三個比較,比較了之前已經(jīng)加入的觀察者的生命周期和當(dāng)前被觀察者的生命周期,parentState的和重入有關(guān)系,所以這里暫時先不討論,后面會分析。這里就拿我們剛才舉例的那個例子來分析,我們在Activity的onResume的生命周期里面加入一個Observer,這時mState為STARTED(因為Activity正在執(zhí)行onResume所以,state還沒有變換),而我們這個是第一個觀察者,所以之前的觀察者為空,所以本次計算的calculateTargetState為STARTED。
while(statefulObserver.mState.compareTo(targetState) < 0 && this.mObserverMap.contains(observer)) {
this.pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(this.mLifecycleOwner, upEvent(statefulObserver.mState));
this.popParentState();
targetState = this.calculateTargetState(observer);
}
這時我們新創(chuàng)建的Observer的生命周期為INITIALIZED,所以肯定是小于targetState,進(jìn)入while循環(huán)。這里的State其實就是一個枚舉,所以compareTo比較的就是枚舉的大小。
public static enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
private State() {
}
public boolean isAtLeast(Lifecycle.State state) {
return this.compareTo(state) >= 0;
}
}
進(jìn)入while循環(huán)后,會首先把Observer加入mParentStates(和重入有關(guān),先不考慮),然后執(zhí)行dispatchEvent,看到這個方法名,其實應(yīng)該就能感受到,這里其實就是執(zhí)行分發(fā)操作.
private static Event upEvent(State state) {
switch(null.$SwitchMap$android$arch$lifecycle$Lifecycle$State[state.ordinal()]) {
case 1:
case 5:
return Event.ON_CREATE;
case 2:
return Event.ON_START;
case 3:
return Event.ON_RESUME;
case 4:
throw new IllegalArgumentException();
default:
throw new IllegalArgumentException("Unexpected state value " + state);
}
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = LifecycleRegistry.getStateAfter(event);
this.mState = LifecycleRegistry.min(this.mState, newState);
this.mLifecycleObserver.onStateChanged(owner, event);
this.mState = newState;
}
可以看到,其實就是按照生命周期的順序,逐步向后分發(fā)。所以我們當(dāng)前的是INITIALIZED,第一次會返回Event.ON_CREATE回調(diào)給觀察者。然后繼續(xù)執(zhí)行calculateTargetState,按照剛才的邏輯,肯定還是小于當(dāng)前的生命周期STARTED,所以會繼續(xù)執(zhí)行while循環(huán)分發(fā)生命周期,直到觀察者的生命周期也是STARTED。
這里我們其實就會有一個結(jié)論,這個其實有點像消息總線里面的粘性,我們在注冊觀察者的時候,會首選將我們的觀察者同步到當(dāng)前被觀察者的生命周期,并且是逐步上升。也就是說我們調(diào)用addObserver的時候,我們注冊的觀察者如果和當(dāng)前被觀察者的生命周期有差異,那么我們會收到回調(diào),然后同步生命周期。
分發(fā)
private void sync() {
while(!this.isSynced()) {
this.mNewEventOccurred = false;
if(this.mState.compareTo(((LifecycleRegistry.ObserverWithState)this.mObserverMap.eldest().getValue()).mState) < 0) {
this.backwardPass();
}
Entry<LifecycleObserver, LifecycleRegistry.ObserverWithState> newest = this.mObserverMap.newest();
if(!this.mNewEventOccurred && newest != null && this.mState.compareTo(((LifecycleRegistry.ObserverWithState)newest.getValue()).mState) > 0) {
this.forwardPass();
}
}
this.mNewEventOccurred = false;
}
到觀察的最后一步了,這里其實就比較簡單了,還是剛才的compareTo邏輯,只不過比較的對象變成了我們觀察者鏈表的頭和尾,我們剛才已經(jīng)加入觀察者,并且同步到最新的生命周期了,這里會再次比較,保證鏈表的首尾的生命周期相同。而backwardPass和forwardPass我這里就不展開了,其實名字就已經(jīng)很直觀的表現(xiàn)了這個方法的作用,就是比較生命周期是需要向前移動還是向后移動,要保證的就是時時刻刻鏈表里的所有的觀察者的生命周期保證一致。
到這里其實注冊觀察者的方法以及分析完成了,剛才上面以及分析了Lifecycle的粘性特性,還剩一個重入沒有說明。這里舉一個例子
@Override
protected void onResume() {
super.onResume();
//加入A-Observer
getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner lifecycleOwner, Lifecycle.Event event) {
if(event == Lifecycle.Event.ON_START){
//移出A-Observer
getLifecycle().removeObserver(this);
//加入B-Observer
getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner lifecycleOwner, Lifecycle.Event event) {
//todo
}
});
}
}
});
}
可能比較繞,我自己也是想了很久才想通的,但是其實可以自己寫個Demo試一試,并且打個斷點,就會發(fā)現(xiàn)Google在這里的設(shè)計還是很巧妙的。這個例子簡單介紹下:
1.我們在Activity的onResume里面注冊了一個觀察者A
2.在A的觀察者的onStart的生命周期里面移出了A自己
3.然后再A的觀察者的onStart的生命周期里面加入了一個新的觀察者B
那么這樣生命周期會怎么回調(diào)呢?按照我們剛才的結(jié)論,我們在onResume里注冊了A,那么A會直接回溯,回調(diào)onCreate和onStart。
然后這時候我們又注冊了B觀察者,這時候我們再看下calculateTargetState方法。
private State calculateTargetState(LifecycleObserver observer) {
Entry<LifecycleObserver, LifecycleRegistry.ObserverWithState> previous = this.mObserverMap.ceil(observer);
State siblingState = previous != null?((LifecycleRegistry.ObserverWithState)previous.getValue()).mState:null;
State parentState = !this.mParentStates.isEmpty()?(State)this.mParentStates.get(this.mParentStates.size() - 1):null;
return min(min(this.mState, siblingState), parentState);
}
方法里的mState就是onResume,而A的生命周期(也就是Pre)是onStart,但是由于我們執(zhí)行了removeObserver把A移出了,那么這時候其實mObserverMap里是一個空的Map,所以這時候mParentStates就出現(xiàn)用處了,先說下結(jié)論mParentStates會在觀察者生命周期回調(diào)的執(zhí)行內(nèi)保存觀察者,生命周期執(zhí)行完成后移出觀察者,所以一般情況下,這個mParentStates都是空的,但是像剛才舉例的這個情況,我們就會發(fā)現(xiàn),我們在A的生命周期內(nèi)移出了A自身,就會導(dǎo)致沒辦法找到最新的觀察者了,如果沒有這個mParentStates,會出現(xiàn)什么問題呢?我們就會發(fā)現(xiàn)B會在A的onStart回調(diào)里回調(diào)onCreate``onStart``onResume,這就會出現(xiàn)一個邏輯性的錯誤,后注冊的觀察者的生命周期比之前注冊的回調(diào)超前了。所以有了mParentStates后,mParentStates會保存A直到A的生命周期執(zhí)行結(jié)束,所以這時候,B就只會執(zhí)行onCreate和onStart的回調(diào)。這個就是我們說的重入問題。
private void forwardPass() {
IteratorWithAdditions ascendingIterator = this.mObserverMap.iteratorWithAdditions();
while(ascendingIterator.hasNext() && !this.mNewEventOccurred) {
Entry<LifecycleObserver, LifecycleRegistry.ObserverWithState> entry = (Entry)ascendingIterator.next();
LifecycleRegistry.ObserverWithState observer = (LifecycleRegistry.ObserverWithState)entry.getValue();
while(observer.mState.compareTo(this.mState) < 0 && !this.mNewEventOccurred && this.mObserverMap.contains(entry.getKey())) {
//放入mParentStates
this.pushParentState(observer.mState);
observer.dispatchEvent(this.mLifecycleOwner, upEvent(observer.mState));
//移出mParentStates
this.popParentState();
}
}
}
private void backwardPass() {
Iterator descendingIterator = this.mObserverMap.descendingIterator();
while(descendingIterator.hasNext() && !this.mNewEventOccurred) {
Entry<LifecycleObserver, LifecycleRegistry.ObserverWithState> entry = (Entry)descendingIterator.next();
LifecycleRegistry.ObserverWithState observer = (LifecycleRegistry.ObserverWithState)entry.getValue();
while(observer.mState.compareTo(this.mState) > 0 && !this.mNewEventOccurred && this.mObserverMap.contains(entry.getKey())) {
Event event = downEvent(observer.mState);
//放入mParentStates
this.pushParentState(getStateAfter(event));
observer.dispatchEvent(this.mLifecycleOwner, event);
//移出mParentStates
this.popParentState();
}
}
}
正常的生命周期分發(fā)
上面觀察和被觀察的兩種都介紹完了,我們再來看一下正常的生命周期分發(fā),就會發(fā)現(xiàn)比較簡單了,首先肯定是我們注入的空Fragment
public class ReportFragment extends Fragment {
private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle.LifecycleDispatcher.report_fragment_tag";
private ReportFragment.ActivityInitializationListener mProcessListener;
public ReportFragment() {
}
public void onDestroy() {
super.onDestroy();
this.dispatch(Event.ON_DESTROY);
this.mProcessListener = null;
}
private void dispatch(Event event) {
Activity activity = this.getActivity();
if(activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner)activity).getLifecycle().handleLifecycleEvent(event);
} else {
if(activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner)activity).getLifecycle();
if(lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry)lifecycle).handleLifecycleEvent(event);
}
}
}
}
}
這里可以看到,在對應(yīng)的生命周期執(zhí)行dispatch方法,對應(yīng)執(zhí)行LifecycleOwner的handleLifecycleEvent方法,而我們知道實現(xiàn)LifecycleOwner的唯一類是LifecycleRegistry。
public void handleLifecycleEvent(Event event) {
this.mState = getStateAfter(event);
if(!this.mHandlingEvent && this.mAddingObserverCounter == 0) {
this.mHandlingEvent = true;
//關(guān)鍵方法同步
this.sync();
this.mHandlingEvent = false;
} else {
this.mNewEventOccurred = true;
}
}
可以看到就會執(zhí)行剛才已經(jīng)看過的同步方法,其實就是把循環(huán),保證鏈表前后的生命周期和mState一致,不一致的話就會逐步通知生命周期。
總結(jié)
至此Lifecycle的生命周期分析完成了,我們對這個總體會有一個認(rèn)知:
- Lifecycle感知生命周期的方式是通過注入一個空的Fragment實現(xiàn)
- 注入的方式有兩種,一個是繼承的Activity自動會注入,一個是在Application感知生命周期注入
- Lifecycle的初始化利用了ContentProvider實現(xiàn)無感知構(gòu)建
- 注冊觀察者的時候會直接粘性的回調(diào)生命周期到當(dāng)前的生命周期
- Lifecycle會保證注冊的觀察者按照注冊順序回調(diào)生命周期,并且考慮了重入的這種復(fù)雜情況
- 還在猶豫什么?趕快體驗吧~