StateFlow
और SharedFlow
फ़्लो एपीआई हैं
जो स्थिति अपडेट को बेहतर तरीके से छोड़ने और एक से ज़्यादा
उपभोक्ताओं को सुरक्षित रखना है.
StateFlow
StateFlow
स्टेट-होल्डर ऑब्ज़र्वेबल फ़्लो है, जो मौजूदा और नई स्थिति का उत्सर्जन करता है
के बारे में अपडेट देते हैं. वर्तमान स्थिति मान को इसके माध्यम से भी पढ़ा जा सकता है
value
प्रॉपर्टी. स्थिति अपडेट करने और उसे फ़्लो में भेजने के लिए,
इसकी value
प्रॉपर्टी
MutableStateFlow
क्लास.
Android में, StateFlow
उन क्लास के लिए सबसे सही है जिन्हें मैनेज करने की ज़रूरत होती है
ऐसी बदली हुई स्थिति हो सकती है जिसका पता लगाया जा सके.
Kotlin फ़्लो से लिए गए उदाहरणों के हिसाब से, StateFlow
LatestNewsViewModel
से दिखाया जा सकता है, ताकि View
यूज़र इंटरफ़ेस (यूआई) की स्थिति से जुड़े अपडेट सुनें और इस वजह से स्क्रीन की मौजूदा स्थिति को बनाए रखें
कॉन्फ़िगरेशन में बदलाव किए गए हैं.
class LatestNewsViewModel(
private val newsRepository: NewsRepository
) : ViewModel() {
// Backing property to avoid state updates from other classes
private val _uiState = MutableStateFlow(LatestNewsUiState.Success(emptyList()))
// The UI collects from this StateFlow to get its state updates
val uiState: StateFlow<LatestNewsUiState> = _uiState
init {
viewModelScope.launch {
newsRepository.favoriteLatestNews
// Update View with the latest favorite news
// Writes to the value property of MutableStateFlow,
// adding a new element to the flow and updating all
// of its collectors
.collect { favoriteNews ->
_uiState.value = LatestNewsUiState.Success(favoriteNews)
}
}
}
}
// Represents different states for the LatestNews screen
sealed class LatestNewsUiState {
data class Success(val news: List<ArticleHeadline>): LatestNewsUiState()
data class Error(val exception: Throwable): LatestNewsUiState()
}
MutableStateFlow
को अपडेट करने के लिए ज़िम्मेदार क्लास, प्रोड्यूसर है.
और StateFlow
से इकट्ठा की जा रही सभी क्लास के उपभोक्ता हैं. नापसंद करें
flow
बिल्डर का इस्तेमाल करके बनाया गया कोल्ड फ़्लो, StateFlow
हॉट होता है:
फ़्लो से इकट्ठा करने पर, कोई प्रोड्यूसर कोड ट्रिगर नहीं होता. StateFlow
हमेशा ऐक्टिव रहता है और मेमोरी में मौजूद होता है. साथ ही, यह बेकार डेटा पाने की ज़रूरी शर्तें पूरी करता है
सिर्फ़ तब इकट्ठा करना, जब किसी कूड़े से इसका कोई और रेफ़रंस न हो
कलेक्शन रूट शामिल है.
जब कोई नया उपभोक्ता, फ़्लो से डेटा इकट्ठा करना शुरू करता है, तो उसे आखिरी
और उसके बाद की स्थितियों में इस्तेमाल किया जा सकता है. आप इस व्यवहार को देख सकते हैं
निगरानी की जा सकती है, जैसे कि
LiveData
.
View
अन्य फ़्लो की तरह ही, StateFlow
को सुनता है:
class LatestNewsActivity : AppCompatActivity() {
private val latestNewsViewModel = // getViewModel()
override fun onCreate(savedInstanceState: Bundle?) {
...
// Start a coroutine in the lifecycle scope
lifecycleScope.launch {
// repeatOnLifecycle launches the block in a new coroutine every time the
// lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.
repeatOnLifecycle(Lifecycle.State.STARTED) {
// Trigger the flow and start listening for values.
// Note that this happens when lifecycle is STARTED and stops
// collecting when the lifecycle is STOPPED
latestNewsViewModel.uiState.collect { uiState ->
// New value received
when (uiState) {
is LatestNewsUiState.Success -> showFavoriteNews(uiState.news)
is LatestNewsUiState.Error -> showError(uiState.exception)
}
}
}
}
}
}
किसी भी फ़्लो को StateFlow
में बदलने के लिए,
stateIn
इंटरमीडिएट ऑपरेटर.
StateFlow, फ़्लो, और LiveData
StateFlow
और LiveData
के पास
समानताएं. दोनों, मॉनिटर किए जा सकने वाले डेटा होल्डर क्लास हैं और दोनों
आपके ऐप्लिकेशन के आर्किटेक्चर में इस्तेमाल किया जाने पर मिलता-जुलता पैटर्न.
हालांकि, ध्यान दें कि StateFlow
और
LiveData
अलग-अलग तरह से काम करते हैं:
StateFlow
को कंस्ट्रक्टर में पास करने के लिए, एक शुरुआती स्थिति की ज़रूरत होती है, जबकिLiveData
नहीं करता है.LiveData.observe()
में उपभोक्ता का रजिस्ट्रेशन अपने-आप रद्द हो जाता है. ऐसा तब होता है, जब व्यू,STOPPED
राज्य को जाता है. वहीं,StateFlow
या कोई भी अन्य फ़्लो अपने-आप इकट्ठा होना बंद नहीं करता. लक्ष्य हासिल करने के लिए बिहेवियर, आपकोLifecycle.repeatOnLifecycle
से फ़्लो इकट्ठा करना होगा ब्लॉक.
shareIn
का इस्तेमाल करके कोल्ड फ़्लो को गर्म करना
StateFlow
एक हॉट फ़्लो है—यह तब तक मेमोरी में बना रहता है, जब तक फ़्लो बना रहता है
इकट्ठा किए गए कॉन्टेंट या इसका कोई अन्य रेफ़रंस, कचरा इकट्ठा करने से जुड़े हों
रूट डालें. कोल्ड फ़्लो को गर्म करने के लिए,
shareIn
ऑपरेटर का इस्तेमाल करें.
Kotlin फ़्लो में बनाए गए callbackFlow
का इस्तेमाल
उदाहरण के लिए, हर कलेक्टर से नया फ़्लो बनाने के बजाय,
shareIn
का इस्तेमाल करके, कलेक्टर के बीच Firestore से हासिल किया गया डेटा.
आपको यह सर्टिफ़िकेट जारी करना होगा:
- फ़्लो को शेयर करने के लिए इस्तेमाल किया जाने वाला
CoroutineScope
. यह स्कोप लाइव होना चाहिए किसी भी उपभोक्ता से ज़्यादा समय तक. - हर नए कलेक्टर को फिर से चलाने के लिए आइटम की संख्या.
- शुरुआती व्यवहार की नीति.
class NewsRemoteDataSource(...,
private val externalScope: CoroutineScope,
) {
val latestNews: Flow<List<ArticleHeadline>> = flow {
...
}.shareIn(
externalScope,
replay = 1,
started = SharingStarted.WhileSubscribed()
)
}
इस उदाहरण में, latestNews
फ़्लो, उत्सर्जित आखिरी आइटम को फिर से चलाता है
नए कलेक्टर के तौर पर जुड़ जाता है और तब तक ऐक्टिव रहता है, जब तक externalScope
और कलेक्टर सक्रिय हैं. SharingStarted.WhileSubscribed()
शुरुआती नीति चालू रहने पर भी, अपस्ट्रीम प्रोड्यूसर को ऐक्टिव रखती है
सदस्य. शुरू करने की अन्य नीतियां उपलब्ध हैं, जैसे कि
तुरंत प्रोड्यूसर बनाने के लिए SharingStarted.Eagerly
या
पहला सदस्य दिखने के बाद, शेयर करने के लिए SharingStarted.Lazily
और फ़्लो को हमेशा चालू रखें.
शेयर किया गयाफ़्लो
shareIn
फ़ंक्शन, SharedFlow
दिखाता है. यह ऐसा हॉट फ़्लो होता है जिससे वैल्यू निकलती हैं
कितना फ़ायदा हो सकता है. SharedFlow
StateFlow
को आसानी से कॉन्फ़िगर किया जा सकता है.
shareIn
का इस्तेमाल किए बिना भी SharedFlow
बनाया जा सकता है. उदाहरण के लिए, अगर आपने
ऐप्लिकेशन के बाकी हिस्सों में टिक भेजने के लिए, SharedFlow
का इस्तेमाल कर सके
सभी कॉन्टेंट एक ही समय पर, समय-समय पर रीफ़्रेश होता रहता है. इसके अलावा
ताज़ा समाचार लाने के लिए, हो सकता है कि आप उपयोगकर्ता को रीफ़्रेश भी करना चाहें
जानकारी वाले सेक्शन में बदलाव करें. निम्न में
कोड स्निपेट, TickHandler
एक SharedFlow
दिखाता है, ताकि अन्य
क्लास को यह पता होता है कि उसका कॉन्टेंट कब रीफ़्रेश करना है. StateFlow
की तरह ही, इसका इस्तेमाल करें:
आइटम भेजने के लिए क्लास में MutableSharedFlow
टाइप की प्रॉपर्टी का बैक अप लेना
फ़्लो के लिए:
// Class that centralizes when the content of the app needs to be refreshed
class TickHandler(
private val externalScope: CoroutineScope,
private val tickIntervalMs: Long = 5000
) {
// Backing property to avoid flow emissions from other classes
private val _tickFlow = MutableSharedFlow<Unit>(replay = 0)
val tickFlow: SharedFlow<Event<String>> = _tickFlow
init {
externalScope.launch {
while(true) {
_tickFlow.emit(Unit)
delay(tickIntervalMs)
}
}
}
}
class NewsRepository(
...,
private val tickHandler: TickHandler,
private val externalScope: CoroutineScope
) {
init {
externalScope.launch {
// Listen for tick updates
tickHandler.tickFlow.collect {
refreshLatestNews()
}
}
}
suspend fun refreshLatestNews() { ... }
...
}
SharedFlow
के काम करने के तरीके को अपनी पसंद के मुताबिक बनाने के लिए, ये तरीके अपनाएं:
replay
आपको नई वैल्यू के लिए, पहले से जनरेट की गई वैल्यू फिर से भेजने की सुविधा देता है सदस्य.onBufferOverflow
की मदद से, बफ़र को चालू करने से जुड़ी नीति तय की जा सकती है भेजे जाने वाले आइटम से भरा हुआ है. डिफ़ॉल्ट मानBufferOverflow.SUSPEND
है, इससे कॉलर को निलंबित कर दिया जाता है. अन्य विकल्प हैं:DROP_LATEST
याDROP_OLDEST
.
MutableSharedFlow
के पास एक subscriptionCount
प्रॉपर्टी भी है, जिसमें यह शामिल है
सक्रिय कलेक्टर की संख्या का इस्तेमाल करें, ताकि आप अपने कारोबार को ऑप्टिमाइज़ कर सकें
तर्क की ज़रूरत होती है. MutableSharedFlow
में एक resetReplayCache
भी शामिल है
फ़ंक्शन का उपयोग करें.
फ़्लो के अन्य संसाधन
- Kotlin की सुविधा Android पर उपलब्ध है
- Android पर Kotlin की जांच करना
- flow के शेयरइन और स्टेटइन ऑपरेटर के बारे में ज़रूरी बातें
- LiveData से Kotlin फ़्लो पर माइग्रेट करना
- Kotlin कोरूटीन और फ़्लो के लिए अतिरिक्त संसाधन