Kotlin Flow ve LiveData


10

Son Google G / Ç'de Jose Alcerreca ve Yiğit Boyar bize veri almak için artık LiveData kullanmamamız gerektiğini söyledi . Şimdi tek seferlik getirmeler için askıya alma işlevlerini kullanmalı ve bir veri akışı oluşturmak için Kotlin'in Akışını kullanmalıyız. Ortak programların tek adımda getirme veya ekleme gibi diğer CRUD işlemleri için mükemmel olduğunu kabul ediyorum. Ancak bir veri akışına ihtiyacım olduğu durumlarda Flow'un bana sağladığı avantajları anlamıyorum. Bana öyle geliyor ki LiveData da aynı şeyi yapıyor.

Flow ile örnek:

ViewModel

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

depo

fun fetchItems() = itemDao.getItems()

Dao

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

LiveData ile örnek:

ViewModel

val items = repository.fetchItems()

depo

fun fetchItems() = itemDao.getItems()

Dao

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

Oda veya Retrofit ile çalışmak için cohoutines ve Flow kullanan projelerin bazı örneklerini de görmek istiyorum. Yalnızca bir kerelik getirme için yardımcı programların kullanıldığı Google'ın ToDo örneğini buldum ve ardından değiştirme sırasında verileri manuel olarak yeniden aldım.

Yanıtlar:


3

Flowbir çeşit reactive stream(rxjava gibi). Bir sürü farklı operatör var .map, buffer()(rxJava'ya kıyasla zaten daha az hayır. Yani, LiveDatave arasındaki temel farklardan Flowbiri, u computation / transformationkullanarak başka bir iş parçacığında haritaya abone olabilmenizdir.

 flowOn(Dispatcher....). 

Yani, örneğin: -

 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 )

İle LiveDatave mapyukarıda can not doğrudan elde edilebilir!

Bu nedenle, akışı depo düzeyinde tutmak ve canlı verileri UI ile depo arasında bir köprü haline getirmek önerilir!

Temel fark, flowsahip olmayan bir dizi farklı operatöre livedatasahip olmasıdır! Ama yine de, projenizi nasıl inşa etmek istiyorsunuz?


3

Adından da anlaşılacağı gibi, Akış'ı, eşzamansız olarak hesaplanan birden çok değerin sürekli akışı gibi düşünebilirsiniz. Benim bakış açımdan, LiveData ve Flow arasındaki ana fark, bir Flow'un sürekli olarak sonuçlar yayınlaması, LiveData'nın tüm veriler getirildiğinde güncellenmesi ve tüm değerleri bir kerede döndürmesidir. Örneğinizde, bence Flow'un tam olarak ne için yapıldığı değil, tek değerler getiriyorsunuz.

Bir Oda örneğim yok, ancak diyelim ki zaman alan bir şey oluşturuyorsunuz, ancak sonraki sonuçları oluştururken ve arabelleğe alırken sonuçları görüntülemek istiyorsunuz.

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

Daha sonra 'Oynatma' işlevinizde, örneğin stuffToPlay'in oluşturulacak nesnelerin bir listesi olduğu sonuçları görüntüleyebilirsiniz:

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'un önemli bir özelliği, oluşturucu kodunun (burada oluşturma işlevi) yalnızca toplandığında çalıştırılmasıdır, dolayısıyla soğuk akış olmasıdır.

Asenkron Akış'taki dokümanlara da başvurabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.