LoginSignup
12
11

More than 3 years have passed since last update.

[Android] LiveEventまとめ

Last updated at Posted at 2020-06-19

LiveDataをイベントの通知(トーストやダイアログを表示指示)として利用する、いわゆるLiveEventの実装をまとめました。

どれを使えばいいの?

結論から先に言うと、hadilq/LiveEventまたは最初の値を無視を使うといいと思います。その他に紹介しているSingleLiveEventEventSingleLiveEvent2は実装に問題があるので使わないほうがいいです。

SingleLiveEvent

architecture-samplesのTODOアプリで昔使われていたやつ。MutableLiveDataを継承しsetValue()等で設定された値は一度だけonChanged()に流れることを保証するクラス。

問題点
複数Observerが存在する場合に、一つのObserverだけにしか値が流れない。

Event

SingleLiveEventの改良。MutableLiveDataを継承した独自クラスではなく、通常のLiveDataEventでラップした値を流す。

https://github.com/android/architecture-samples/blob/todo-mvvm-live-kotlin/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/Event.kt
https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

改善点
一度だけ値を取得できるgetContentIfNotHandled()と常に値を取得できるpeekContent()の2種類のインターフェースを提供することで、Viewにイベントを通知しつつLoggerで毎回値を取得するようなユースケースは達成できるようになった。

問題点
SingleLiveEventと同じく、イベントとして購読したいObserverが2つ以上ある場合には利用できない。
値をラップしないと使えないので若干冗長。

SingleLiveEvent2

SingleLiveEventの改良。MutableLiveDataを継承した独自クラスでObserverMutableSetを管理し、全てのObserverに対して一度だけonChanged()が呼ばれるようにする。

改善点
Eventで実現できない複数Observerに対するイベントの通知を実現。

問題点
最初に購読したLifecycleOwnerのライフサイクルに、その後購読した全てのObserverが従ってしまう。

最初の値を無視

LiveDataでイベントを扱った時に起こる問題は最新の値がキャッシュされることに起因するので、それを排除するというアプローチ。LiveDataobserve()の両方を拡張関数で手を入れることでキャッシュされる値を無視する。

利点
シンプルな拡張でイベントの通知を実現。

問題点
LiveDataobserve()の両方が正しく揃うことで動作するので、他の実装に比べてバグが混入しやすい。

hadilq/LiveEvent

MediatorLiveDataを継承した独自クラスの内部でObserverをラップするObserverWrapperを生成、その中で一度だけのイベント通知を実現している。

利点
ライブラリとして簡単に利用できる。

問題点
無さそうに思える。

まとめ

手法 複数Observer対応 イベントが発生した後の購読で値が流れない
SingleLiveEvent × ×
Event ×
SingleLiveEvent2
最初の値を無視
hadilq/LiveEvent
12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11