()のAndroidの作品JetpackのアーキテクチャLiveDataコンポーネント

アリP7モバイルインターネットの建築家、無料の学習のための高度なビデオ(毎日更新)、クリックしてください:https://space.bilibili.com/474380680

序文

LiveData作業を説明するために、この記事の主な原則は、LiveDataどうかを知り、そして、していない公式ドキュメントを参照してください
あなたがライフサイクルを知っていない場合は、知識のライフサイクルに関連するLiveDataの説明は、ドキュメントのライフサイクルの導入を参照してください

入門

LiveDataデータ保持クラスであり、それは他の構成要素を変更する観察者を追加することによって観察することができます。通常の観察者とは異なり、その最も重要な特徴は、データが更新された場合、このような活動のように、アプリケーションのライフサイクルに準拠しているが、活動状態、LivaeDataしません通知活動(オブザーバー)を破壊します。もちろん。LiveDataなどないメモリリークが発生しますなど、多くの利点が、あります。

使用することが多いのViewModelとLiveData、更新データをトリガする責任ViewModelに、LiveDataへの更新通知は、その後、LiveDataは、アクティブなオブザーバーの地位を通知します。

原理分析

以下のコードで直接見て:

public class UserProfileViewModel extends ViewModel {
    private String userId;
    private MutableLiveData<User> user;
    private UserRepository userRepo;

    public void init(String userId) {
        this.userId = userId;
        userRepo = new UserRepository();
        user = userRepo.getUser(userId);
    }

    public void refresh(String userId) {
        user = userRepo.getUser(userId);
    }

    public MutableLiveData<User> getUser() {
        return user;
    }

}

内部ホルダUserRepository UserProfileViewModel MutableLiveData <ユーザー>参照、上記とネットワークまたはデータベースからデータを取得した後MutableLiveDataビューモデルにパッケージに供給する責任UserRepository()のMutableLiveDataのgetUserを得る方法を提供します。

私たちは、<ユーザー> MutableLiveDataためUserProfileFragment登録オブザーバは、次の通り:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    String userId = getArguments().getString(UID_KEY);
    viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);
    viewModel.init(userId);
    //标注1
    viewModel.getUser().observe(UserProfileFragment.this, new Observer<User>() {
        @Override
        public void onChanged(@Nullable User user) {
            if (user != null) {
                tvUser.setText(user.toString());
            }
        }
    });
}

MutableLiveData <ユーザー>私たちのLiveDataで取得するにはラベル1、viewModel.getUser(見)は、その後、メソッドLiveDataオブザーバを呼び出し、UserProfileFragmentはどこへ行くの引数として渡されました。オブザーバー()メソッドは、我々の分析の入り口で、我々は観察者のLiveDataを参照してください()メソッドが実行されます:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
    //标注1
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    //标注2
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, 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;
    }
    owner.getLifecycle().addObserver(wrapper);
}

あなたのサポートパッケージバージョン以上26.1.0は、フラグメントデフォルト・サポート・パッケージには、コンポーネントのライフサイクルに利用可能LifecycleOwner、およびLifecycleOwnerから継承された場合UserProfileFragmentが渡さLifeCycleOwnerパラメータとして、また知る、見ることができますライフサイクルUserProfileFragmentコンポーネント(ここでは、デフォルトのライフサイクルAを知る必要はあり)。

ラベル1を見て、私たちUserProfileFragmentコンポーネントがすでに状態を破壊した場合、それはリターンを指示する、それが観察者のランクに追加されません。状態を破壊していない場合は、2のマークに行き、新しいLifecycleBoundObserverは)私たちのLifecycleOwnerを保存し、観察者まで、その後、地図、putIfAbsent(へのオブザーバーとラッパーのキーと値として、それぞれmObservers.putIfAbsent(オブザーバー、ラッパー)、呼び出しこの方法は、それ以外の場合はNULLを返し、値が、リターンが存在するかどうかを判断することができたであろう。
リターン既存nullの場合は、説明はこの観察者に追加されていなかった、観察者は、それがUserProfileFragmentライフサイクルオブザーバーとして、ライフサイクルの所有者としてLifecycleBoundObserverあるでしょう。

私たちは、LifecycleBoundObserverソースを見て:

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
    @NonNull final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
        super(observer);
        mOwner = owner;
    }

    @Override
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        activeStateChanged(shouldBeActive());
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }

    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

コードは非常に、LifecycleBoundObserverはあなたがLifecycleOwnerのステータスを取得するためのイニシアチブを知覚または取ることができLifecycleOwnerオブザーバに参加ObserverWrapperから継承されたとGenericLifecycleObserverインタフェースを実装し、インターフェイスはLifecycleObserver GenericLifecycleObserverインタフェースから継承した、そしてライフサイクルは、インターフェイスの特性に応じたとLifecycleObserverを達成されていません。

さて、それから、私たちのLiveDataをオブザーバを読んだ後、それは視聴者に通知するとき?私たちは次のようにここで私はUserRepository直接アナログネットワークを要求し、MutableLiveDataにユーザーにイニシアチブをとるだろう、そのような要求の後にネットワークがユーザー情報に戻るには、確かにデータの更新を考えると、私たち自身のコードコントロールのデータを更新しません。

public class UserRepository {
    final MutableLiveData<User> data = new MutableLiveData<>();

    public MutableLiveData<User> getUser(final String userId) {
        if ("xiasm".equals(userId)) {
            data.setValue(new User(userId, "夏胜明"));
        } else if ("123456".equals(userId)) {
            data.setValue(new User(userId, "哈哈哈"));
        } else {
            data.setValue(new User(userId, "unknow"));
        }
        return data;
    }
}

getUser()メソッドを呼び出すとき、私たちはMutableLiveDataにここにLiveDataにMutableLiveData実際LiveDataから継承されたデータを置くためのsetValue()メソッドを呼び出して、何も特別な:

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);
    }
}

setValue()は、ユーザーが配置され、postValueは、このチェックを持っていないとき、それ以外の場合はエラーになり、メインスレッドである必要がありますが、メインスレッドにデータを渡します。私たちは、直接のsetValue()メソッドを見て:

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

最初の呼び出しassertMainThread()メインスレッドかどうかを確認し、MDATA、その後、dispatchingValueを呼び出す()メソッドを更新し、nullを渡しするデータを割り当てるには、データは、私たちのUserProfileFragmentなど様々なオブザーバーに配布されます。dispatchingValue()メソッドの実装を見て:

private void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        //标注1
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
            //标注2
            for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

マークされた1から分かるように、dispatchingValue()とヌルパラメータ渡さ差を通過しないようである渡されたヌルヌル着信観察者の通知のみに対し、その観察者のすべてに通知する場合。私たちは)実際には、我々はオブザーバーがconsiderNotify(呼び出し通知、LifecycleBoundObserver上記、達成知らせることです具体的な方法を、直接2のラベルが付い見て、すべてのObserverWrapper GET、mObserversを横断することによって、すべてのオブザーバに通知します。

private void considerNotify(ObserverWrapper observer) {
    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.
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    //noinspection unchecked
    observer.mObserver.onChanged((T) mData);
}

観察者がアクティブでない場合は、視聴者がこれに気づかないだろう、最後の行を見てみると、((T)MDATA)observer.mObserver.onChanged、observer.mObserverは、私たちがオブザーバーLiveData()メソッドを呼び出し、その後、オブザーバーを渡さ呼んでいます着信データMDATAを保存するonChangedイベント((T)MDATA)法の観察者は、また、更新を実現します。私たちの表情オブザーバーの実現には:

viewModel.getUser().observe(UserProfileFragment.this, new Observer<User>() {
    @Override
    public void onChanged(@Nullable User user) {
        if (user != null) {
            tvUser.setText(user.toString());
        }
    }
});

変更や更新に任意のコントロールがユーザーに応じている場合は、()メソッドonChangedイベントでそれに対処します。ここで、LiveDataは、実際には、LiveDataの実装はまだライフサイクルに依存する必要があり、オーバー解析することができました。

オリジナルリンク:https://www.jianshu.com/p/21bb6c0f8a5a
アリP7モバイルインターネットの建築家、無料の学習のための高度なビデオ(毎日更新)、クリックしてください:https://space.bilibili.com/474380680

おすすめ

転載: www.cnblogs.com/Android-Alvin/p/12109373.html