Kotlin Flow vs LiveData

10

Di Google I / O terakhir, Jose Alcerreca dan Yigit Boyar memberi tahu kami bahwa kami tidak boleh lagi menggunakan LiveData untuk mengambil data. Sekarang kita harus menggunakan fungsi menangguhkan untuk pengambilan satu-jepretan dan menggunakan Aliran Kotlin untuk membuat aliran data. Saya setuju bahwa coroutine sangat bagus untuk pengambilan satu-shot atau operasi CRUD lainnya, seperti menyisipkan, dll. Tetapi dalam kasus-kasus di mana saya membutuhkan aliran data, saya tidak mengerti apa keuntungan yang diberikan Flow kepada saya. Sepertinya saya bahwa LiveData melakukan hal yang sama.

Contoh dengan Flow:

ViewModel

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

Gudang

fun fetchItems() = itemDao.getItems()

Dao

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

Contoh dengan LiveData:

ViewModel

val items = repository.fetchItems()

Gudang

fun fetchItems() = itemDao.getItems()

Dao

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

Saya juga ingin melihat beberapa contoh proyek menggunakan coroutine dan Flow untuk bekerja dengan Room atau Retrofit. Saya hanya menemukan sampel ToDo Google di mana coroutine digunakan untuk pengambilan satu-jepretan kemudian secara manual mengambil data tentang perubahan.

Dmitry Simakov
sumber

Jawaban:

3

Flowadalah semacam reactive stream(seperti rxjava). Ada banyak operator yang berbeda seperti .map, buffer()(toh kurang. Operator dibandingkan dengan rxJava). Jadi, salah satu perbedaan utama antara LiveDatadan Flowadalah bahwa Anda dapat berlangganan peta computation / transformationmenggunakan beberapa utas lainnya

 flowOn(Dispatcher....). 

Jadi, misalnya: -

 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 )

Dengan LiveDatadan map, hal-hal di atas tidak dapat dicapai secara langsung!

Jadi disarankan untuk terus mengalir di level repositori, dan jadikan livedata jembatan antara UI dan repositori!

Perbedaan utama adalah bahwa flowada banyak operator berbeda yang livedatatidak memilikinya! Tetapi sekali lagi, Terserah Anda bagaimana Anda ingin membangun proyek Anda!

Santanu Sur
sumber
3

Seperti namanya, Anda dapat menganggap Flow seperti aliran kontinu dari beberapa nilai yang dihitung secara asinkron. Perbedaan utama antara LiveData dan Flow, dari sudut pandang saya, adalah bahwa Flow terus-menerus mengeluarkan hasil sementara LiveData akan memperbarui ketika semua data diambil dan mengembalikan semua nilai sekaligus. Dalam contoh Anda, Anda mengambil nilai tunggal, yang tidak sesuai dengan apa yang dibuat oleh Flow menurut saya.

Saya tidak memiliki contoh Kamar tetapi katakanlah Anda sedang merender sesuatu yang membutuhkan waktu, tetapi Anda ingin menampilkan hasil sambil merender dan menyangga hasil selanjutnya.

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

Kemudian dalam fungsi 'Playback' Anda dapat misalnya menampilkan hasil di mana stuffToPlay adalah Daftar objek yang akan di-render, seperti:

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

Karakteristik penting Flow adalah kode pembangunnya (fungsi render di sini) hanya dieksekusi, ketika dikumpulkan, karenanya merupakan aliran dingin .

Anda juga dapat merujuk ke dokumen di Asynchronous Flow

nulldroid
sumber