LiveData使用とソース解析
33680 ワード
前編ではLifecycleについて述べていますが、MVPモードを使って開発したいなら、P層にLifecycleのこの特性を利用させることができます.P層はライフサイクルを感知することができます.これはP層にとって大きな向上です.もちろん、これはLifecycleの運用にすぎません.これはLifecycleのもう一つの運用です.それはLifecycleのもう一つの運用です.それはLiveDataです.その設計は観察者モードを用いており,データが変化するとUIを自動的に更新することができ,その使用により論理的な処理に専念することができる.
LiveData使用
上のコードは比較的簡単で、簡単に3つのステップを概略的に使用することができます.MutableLiveDataオブジェクトを作成します.このオブジェクトの主な役割はデータを保存することです. MutableLiveDataにオブザーバーを設定します.このオブザーバー(Observer)は、設定データまたはデータが変更されるとコールバックされます. MutableLiveDataにデータを設定する.この3ステップが完了すると、MutableLiveDataのフル使用が完了します.次に、どのように実現されているかを見てみましょう.まず、MutableLiveData: を見てみましょう.
LiveDataから継承し、親を呼び出す方法(LiveDataの2つの方法はprotected)です.ここでは主にデータを設定して使用します.ここで提供される2つの方法には違いがあります.主にpostValue()はサブスレッドで使用できます.これが彼らの使い方の違いです.LiveDataのコードはそれほど多くありません.興味のあるものはすべて見てみましょう.ここではコードクリップでゆっくり分析し、まずobserve()を見て、観察者を追加します.
以上の主な論理フローをまとめると、observerを追加するとき、実はLifecycleにLifecycleObserverを追加することで、対応するライフサイクルでobserverを処理することができます.もちろん、このobserverのコールバックは常に呼び出されるわけではありません.データが変更されたり、データが設定されたりしたときにのみ呼び出されます.次に、dispatchingValueの実行ロジックを見てみましょう.
ライフサイクルトリガまたは設定値に関係なく、最終的に呼び出されるのはconsiderNotify()メソッドです.
ここでは、データを設定する方法を見てみましょう.
実は上で分析したdispatchingValue()の方法で、ここでmVersionは自増して、データが変化したことを説明します.postValue()のみが、結局setValue()に呼び出され、1つのスレッド間の切り替えが増えたにすぎない.よし、これで终わっても、全体的に理解しにくいわけではありません.もし疑问があれば、一绪に指正を学ぶことを歓迎します!!
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つのステップを概略的に使用することができます.
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つのスレッド間の切り替えが増えたにすぎない.よし、これで终わっても、全体的に理解しにくいわけではありません.もし疑问があれば、一绪に指正を学ぶことを歓迎します!!