Android Jetpack--lifecycle全解析

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行代碼,還有不少一部分是注釋,感興趣可以自行閱讀。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容