Kotlin FlowとLiveData


10

前回のGoogle I / Oで、Jose AlcerrecaとYigit Boyar 、LiveDataを使用してデータをフェッチすることはもうやめるべきだと言っていました。ここで、ワンショットフェッチに中断関数を使用し、Kotlinのフローを使用してデータストリームを作成する必要があります。コルーチンはワンショットフェッチや挿入などの他のCRUD操作に最適であることに同意します。しかし、データストリームが必要な場合、Flowがどのような利点をもたらすかわかりません。LiveDataも同じことをしているようです。

フローの例:

ViewModel

val items = repository.fetchItems().asLiveData()

リポジトリー

fun fetchItems() = itemDao.getItems()

ダオ

@Query("SELECT * FROM item")
fun getItems(): Flow<List<Item>>

LiveDataの例:

ViewModel

val items = repository.fetchItems()

リポジトリー

fun fetchItems() = itemDao.getItems()

ダオ

@Query("SELECT * FROM item")
fun getItems(): LiveData<List<Item>>

また、コルーチンとFlowを使用してRoomまたはRetrofitを操作するプロジェクトの例もいくつか見たいと思います。コルーチンがワンショットフェッチに使用され、変更時にデータを手動で再フェッチするGoogleのToDoサンプルのみが見つかりました。

回答:


3

Flow一種のreactive stream(rxjavaのような)。以下のような異なるオペレータの束があり.mapbuffer()(とにかくあまりありませんが。オペレータのrxJavaと比較して)。だから、主な違いの一つLiveDataとは、Flowuはマップを購読することができるということですcomputation / transformation使用して、いくつかの他のスレッドに

 flowOn(Dispatcher....). 

したがって、たとえば:-

 flowOf("A","B","C").map { compute(it) }.flowOn(Dispatchers.IO).collect {...} // U can change the execution thread of the computation ( by default its in the same dispatcher as collect )

LiveDatamap、上記カントは直接達成されます!

したがって、リポジトリレベルでフローを維持し、livedataをUIとリポジトリの間のブリッジにすることをお勧めします。

主な違いは、flow多くの異なる演算子をlivedata持たないことです!しかし、繰り返しますが、どのようにしてプロジェクトを構築したいのでしょうか。


3

名前が示すように、Flowは、非同期に計算された複数の値の連続したフローのようなものと考えることができます。私の観点から見ると、LiveDataとFlowの主な違いは、すべてのデータがフェッチされてすべての値が一度に返されるとLiveDataが更新されるのに対し、Flowは継続的に結果を出力することです。あなたの例では、単一の値をフェッチしていますが、これは、私の考えではFlowが作成したものとは正確には一致していません。

Roomの例はありませんが、時間のかかるものをレンダリングしているが、次の結果をレンダリングおよびバッファリングしながら結果を表示したいとします。

private fun render(stuffToPlay: List<Any>): Flow<Sample> = flow {
     val sample = Sample()
     // computationally intensive operation on stuffToPlay
     Thread.sleep(2000)
     emit(sample)
}

次に、「再生」関数で、たとえばstuffToPlayがレンダリングするオブジェクトのリストである結果を表示できます。

playbackJob = GlobalScope.launch(Dispatchers.Default) {

    render(stuffToPlay)
        .buffer(1000)   // tells the Flow how many values should be calculated in advance

        .onCompletion {
            // gets called when all stuff got played
        }
        .collect{sample ->
           // collect the next value in the buffered queue
           // e.g. display sample
        }
}

Flowの重要な特徴は、それが収集されたときにのみ実行されるビルダーコード(ここではレンダリング関数)であるため、コールドストリームであることです。

非同期フローのドキュメントを参照することもできます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.