StateFlow
এবং SharedFlow
হল ফ্লো API যা ফ্লোকে সর্বোত্তমভাবে স্টেট আপডেট নির্গত করতে এবং একাধিক ভোক্তাদের কাছে মান নির্গত করতে সক্ষম করে।
StateFlow
StateFlow
হল একটি স্টেট-হোল্ডার পর্যবেক্ষণযোগ্য প্রবাহ যা বর্তমান এবং নতুন স্টেট আপডেটগুলি তার সংগ্রাহকদের কাছে প্রকাশ করে। বর্তমান রাষ্ট্র মান তার value
সম্পত্তি মাধ্যমে পড়া যেতে পারে. স্টেট আপডেট করতে এবং ফ্লোতে পাঠাতে, MutableStateFlow
ক্লাসের value
সম্পত্তিতে একটি নতুন মান বরাদ্দ করুন।
অ্যান্ড্রয়েডে, StateFlow
সেই ক্লাসগুলির জন্য একটি দুর্দান্ত ফিট যা একটি পর্যবেক্ষণযোগ্য পরিবর্তনযোগ্য অবস্থা বজায় রাখতে হবে।
Kotlin ফ্লো থেকে উদাহরণগুলি অনুসরণ করে, একটি StateFlow
LatestNewsViewModel
থেকে উন্মুক্ত করা যেতে পারে যাতে View
UI অবস্থার আপডেট শুনতে পারে এবং অন্তর্নিহিতভাবে স্ক্রিন স্টেটকে কনফিগারেশন পরিবর্তনগুলিকে বাঁচিয়ে রাখতে পারে৷
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
তা করে না। -
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
ফাংশনও থাকে যদি আপনি ফ্লোতে পাঠানো সর্বশেষ তথ্য রিপ্লে করতে না চান।
অতিরিক্ত প্রবাহ সম্পদ
- কোটলিন অ্যান্ড্রয়েডে প্রবাহিত হয়
- কোটলিন টেস্টিং অ্যান্ড্রয়েডে প্রবাহিত হয়
- Flow এর shareIn এবং stateIn অপারেটর সম্পর্কে জানার বিষয়
- লাইভডেটা থেকে কোটলিন ফ্লোতে স্থানান্তরিত হচ্ছে
- কোটলিন কোরোটিন এবং প্রবাহের জন্য অতিরিক্ত সংস্থান