LiveData使用とソース解析

33680 ワード

前編ではLifecycleについて述べていますが、MVPモードを使って開発したいなら、P層にLifecycleのこの特性を利用させることができます.P層はライフサイクルを感知することができます.これはP層にとって大きな向上です.もちろん、これはLifecycleの運用にすぎません.これはLifecycleのもう一つの運用です.それはLifecycleのもう一つの運用です.それはLiveDataです.その設計は観察者モードを用いており,データが変化するとUIを自動的に更新することができ,その使用により論理的な処理に専念することができる.
LiveData使用
public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";
    private MutableLiveData<String> data  = new MutableLiveData<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        TextView textView = findViewById(R.id.textView);
        data.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });
        findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                data.setValue("tangedegushi");
            }
        });
    }
}

上のコードは比較的簡単で、簡単に3つのステップを概略的に使用することができます.
  • MutableLiveDataオブジェクトを作成します.このオブジェクトの主な役割はデータを保存することです.
  • MutableLiveDataにオブザーバーを設定します.このオブザーバー(Observer)は、設定データまたはデータが変更されるとコールバックされます.
  • MutableLiveDataにデータを設定する.この3ステップが完了すると、MutableLiveDataのフル使用が完了します.次に、どのように実現されているかを見てみましょう.まず、MutableLiveData:
  • を見てみましょう.
    public class MutableLiveData<T> extends LiveData<T> {
        @Override
        public void postValue(T value) {
            super.postValue(value);
        }
    
        @Override
        public void setValue(T value) {
            super.setValue(value);
        }
    }
    

    LiveDataから継承し、親を呼び出す方法(LiveDataの2つの方法はprotected)です.ここでは主にデータを設定して使用します.ここで提供される2つの方法には違いがあります.主にpostValue()はサブスレッドで使用できます.これが彼らの使い方の違いです.LiveDataのコードはそれほど多くありません.興味のあるものはすべて見てみましょう.ここではコードクリップでゆっくり分析し、まずobserve()を見て、観察者を追加します.
        @MainThread
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
            if (owner.getLifecycle().getCurrentState() == DESTROYED) {
                // ignore
                return;
            }
            //   Observer    ,                 ,      
            //LifecycleBoundObserver     Lifecycle
            LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
            // observer    ,             
            ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
            if (existing != null && !existing.isAttachedTo(owner)) {
                throw new IllegalArgumentException("Cannot add the same observer"
                        + " with different lifecycles");
            }
            if (existing != null) {
                return;
            }
            // Lifecycle      ,              
            owner.getLifecycle().addObserver(wrapper);
        }
        class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
            @NonNull final LifecycleOwner mOwner;
    
            LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
                super(observer);
                mOwner = owner;
            }
    
            @Override
            boolean shouldBeActive() {
            //       observer            ,      STARTED    ,               onStart()        
            // onStart()     onStop()           true
                return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
            }
    
    		//          ,            ,          
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            //   activity onDestroy() ,       observer       
                if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                    removeObserver(mObserver);
                    return;
                }
                activeStateChanged(shouldBeActive());
            }
    
            @Override
            boolean isAttachedTo(LifecycleOwner owner) {
                return mOwner == owner;
            }
    
            @Override
            void detachObserver() {
            //   activity onDestroy()     ,  Lifecycle     
                mOwner.getLifecycle().removeObserver(this);
            }
        }
        private abstract class ObserverWrapper {
            final Observer<T> mObserver;
            boolean mActive;
            int mLastVersion = START_VERSION;
    
            ObserverWrapper(Observer<T> observer) {
                mObserver = observer;
            }
    
            abstract boolean shouldBeActive();
    
            boolean isAttachedTo(LifecycleOwner owner) {
                return false;
            }
    
            void detachObserver() {
            }
    
            void activeStateChanged(boolean newActive) {
            //mActive      false , onStart   ,    newActive   false ,            observer onStart()           
                if (newActive == mActive) {
                    return;
                }
                // immediately set active state, so we'd never dispatch anything to inactive
                // owner
                mActive = newActive;
                boolean wasInactive = LiveData.this.mActiveCount == 0;
                LiveData.this.mActiveCount += mActive ? 1 : -1;
                if (wasInactive && mActive) {
                //      observer,      , onStart()  ,         ,    observer    
                    onActive();
                }
                if (LiveData.this.mActiveCount == 0 && !mActive) {
                // LivaData    ,         ,          
                    onInactive();
                }
                if (mActive) {
                //     observer     ,        observer      
                    dispatchingValue(this);
                }
            }
        }
    

    以上の主な論理フローをまとめると、observerを追加するとき、実はLifecycleにLifecycleObserverを追加することで、対応するライフサイクルでobserverを処理することができます.もちろん、このobserverのコールバックは常に呼び出されるわけではありません.データが変更されたり、データが設定されたりしたときにのみ呼び出されます.次に、dispatchingValueの実行ロジックを見てみましょう.
        private void dispatchingValue(@Nullable ObserverWrapper initiator) {
        //      observer,       ,mDispatchInvalidated         ,        
            if (mDispatchingValue) {
                mDispatchInvalidated = true;
                return;
            }
            mDispatchingValue = true;
            do {
                mDispatchInvalidated = false;
                if (initiator != null) {
                //                 ,      LicycleObserver              
                    considerNotify(initiator);
                    initiator = null;
                } else {
                //            observer      
                    for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                            mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                        considerNotify(iterator.next().getValue());
                        if (mDispatchInvalidated) {
                            break;
                        }
                    }
                }
            } while (mDispatchInvalidated);
            mDispatchingValue = false;
        }
    

    ライフサイクルトリガまたは設定値に関係なく、最終的に呼び出されるのはconsiderNotify()メソッドです.
        private void considerNotify(ObserverWrapper observer) {
        //   observer          ,   onStart()    false 
            if (!observer.mActive) {
                return;
            }
            // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
            //
            // we still first check observer.active to keep it as the entrance for events. So even if
            // the observer moved to an active state, if we've not received that event, we better not
            // notify for a more predictable notification order.
            //    activity           observer    , onCreate() onStart()     true,   				     
            // onStop       true,         observer    
            if (!observer.shouldBeActive()) {
                observer.activeStateChanged(false);
                return;
            }
            //              ,          
            if (observer.mLastVersion >= mVersion) {
                return;
            }
            observer.mLastVersion = mVersion;
            //noinspection unchecked
            //       observer   
            observer.mObserver.onChanged((T) mData);
        }
    

    ここでは、データを設定する方法を見てみましょう.
        protected void setValue(T value) {
            assertMainThread("setValue");
            mVersion++;
            mData = value;
            dispatchingValue(null);
        }
    

    実は上で分析したdispatchingValue()の方法で、ここでmVersionは自増して、データが変化したことを説明します.postValue()のみが、結局setValue()に呼び出され、1つのスレッド間の切り替えが増えたにすぎない.よし、これで终わっても、全体的に理解しにくいわけではありません.もし疑问があれば、一绪に指正を学ぶことを歓迎します!!