कोटलिन फ्लो बनाम लाइवडाटा


10

अंतिम Google I / O में, जोस एलिसरेका और यिजिट बॉयर ने हमें बताया कि हमें डेटा लाने के लिए अब LiveData का उपयोग नहीं करना चाहिए। अब हमें एक-शॉट वाले भ्रूणों के लिए निलंबित कार्यों का उपयोग करना चाहिए और डेटा स्ट्रीम बनाने के लिए कोटलिन के फ्लो का उपयोग करना चाहिए। मैं इस बात से सहमत हूं कि एक-शॉट प्राप्त करने या अन्य CRUD संचालन, जैसे डालने के लिए, आदि के लिए कोराउटाइन महान हैं, लेकिन ऐसे मामलों में जहां मुझे डेटा स्ट्रीम की आवश्यकता होती है, मुझे समझ नहीं आता कि मुझे क्या फ़ायदा होता है। मुझे ऐसा लगता है कि 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>>

मैं कोरटाइन और फ्लो का उपयोग करने वाले प्रोजेक्ट्स के कुछ उदाहरणों को भी देखना चाहूंगा। मुझे केवल एक Google का ToDo नमूना मिला जहाँ coroutines का उपयोग एक-शॉट प्राप्त करने के लिए किया जाता है और फिर मैन्युअल रूप से डेटा को बदलने पर वापस ले जाता है।

जवाबों:


3

Flowएक तरह है reactive stream(जैसे rxjava)। विभिन्न संचालकों का एक समूह है .map, जैसे कि buffer()(rxJava की तुलना में ऑपरेटर के किसी भी तरह से कम नहीं)। तो, के बीच मुख्य अंतर में से एक LiveDataऔर Flowहै कि यू नक्शा सदस्यता ले सकते हैं है 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 )

साथ LiveDataऔर map, ऊपर नहीं कर सकते सीधे प्राप्त किया जा!

तो इसकी सिफारिश रिपॉजिटरी स्तर में प्रवाह रखने के लिए, और लिवेटा को यूआई और रिपॉजिटरी के बीच एक पुल बनाने के लिए किया जाता है!

मुख्य अंतर यह है कि flowविभिन्न ऑपरेटरों का एक गुच्छा मिला है जो livedataनहीं है! लेकिन फिर से, यह अप करने के लिए कैसे आप अपनी परियोजना का निर्माण करना चाहते हैं!


3

जैसा कि नाम से पता चलता है, आप कई अतुल्यकालिक गणना मूल्यों के निरंतर प्रवाह की तरह प्रवाह के बारे में सोच सकते हैं। मेरे दृष्टिकोण से, LiveData और Flow के बीच मुख्य अंतर यह है कि एक प्रवाह लगातार परिणाम निकालता है जबकि LiveData अपडेट करेगा जब सभी डेटा प्राप्त हो जाएगा और एक बार में सभी मान वापस कर देगा। आपके उदाहरण में आप एकल मान ला रहे हैं, जो कि मेरे विचार से फ्लो नहीं बनाया गया था।

मेरे पास एक कक्ष उदाहरण नहीं है, लेकिन मान लें कि आप कुछ ऐसा कर रहे हैं जिसमें समय लगता है, लेकिन आप अगले परिणामों का प्रतिपादन और बफरिंग करते हुए परिणाम प्रदर्शित करना चाहते हैं।

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

फ्लो की एक महत्वपूर्ण विशेषता यह है कि यह बिल्डर कोड (यहां फ़ंक्शन प्रदान करता है) केवल निष्पादित होता है, जब यह एकत्र हो जाता है, इसलिए इसकी एक ठंडी धारा होती है।

आप असिंक्रोनस फ़्लो में डॉक्स का भी उल्लेख कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.