【JetPack系列】——Lifecycle源碼分析

本系列博客基于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)用LifecycleRegistryhandlerLifecycleEvent方法。
所以這里我們可以得出一個結(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() {
    }
}

這樣就比較清晰了,可以看到其實通過ApplicationregisterActivityLifecycleCallbacks方法,來向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);
            }

這一步我個人感覺其實是LifecycleLiveData的核心思想,這里首先提一問題:

如果在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,這時mStateSTARTED(因為Activity正在執(zhí)行onResume所以,state還沒有變換),而我們這個是第一個觀察者,所以之前的觀察者為空,所以本次計算的calculateTargetStateSTARTED。

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)加入觀察者,并且同步到最新的生命周期了,這里會再次比較,保證鏈表的首尾的生命周期相同。而backwardPassforwardPass我這里就不展開了,其實名字就已經(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)onCreateonStart
然后這時候我們又注冊了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í)行onCreateonStart的回調(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í)行LifecycleOwnerhandleLifecycleEvent方法,而我們知道實現(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ù)雜情況
  • 還在猶豫什么?趕快體驗吧~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容