MVI mimarisinde kaydedilmesi gerekmeyen olaylar nasıl işlenir?
sobes.tech yapay zeka
AI'dan gelen yanıt
MVI'de tek seferlik olayları (örneğin, Toast gösterme, gezinme) işlemek için, bunların View veya duruma yeniden oluşturulmadan kalmaması gereken durumlar için çeşitli yaklaşımlar kullanılır:
-
Yan Etkiler (SingleLiveEvent / Kanallar):
ViewModel'den View'e olay göndermek için özel bir mekanizma.
SingleLiveEvent(eski projelerde veyaandroidx.lifecycle:lifecycle-livedata-ktxgibi kütüphanelerde) veya Flow'danChannel(modern projelerde). Bu, olayın yalnızca bir kez tüketilmesini garanti eder.// Flow ve Channel ile ViewModel import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.receiveAsFlow import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch class MyViewModel : ViewModel() { private val _sideEffect = Channel<SideEffect>(Channel.BUFFERED) val sideEffect = _sideEffect.receiveAsFlow() fun doSomething() { // İş mantığı... viewModelScope.launch { _sideEffect.send(SideEffect.ShowToast("İşlem başarıyla tamamlandı!")) } } } sealed class SideEffect { data class ShowToast(val message: String) : SideEffect() object NavigateNext : SideEffect() } // View'da (Fragment/Activity) SideEffect izleniyor import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch class MyFragment : Fragment() { private val viewModel: MyViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewLifecycleOwner.lifecycleScope.launch { viewModel.sideEffect.collect { effect -> when (effect) { is SideEffect.ShowToast -> showToast(effect.message) SideEffect.NavigateNext -> navigateToNextScreen() } } } } private fun showToast(message: String) { // Toast gösterimi } private fun navigateToNextScreen() { // Navigasyon } } -
State'te Tek Kullanımlık Olaylar:
Daha az tercih edilen bir yöntemdir, ancak bazen basit durumlarda kullanılır.
UiState'e, tek kullanımlık olayın varlığını belirten bir bayrak veya alan eklenir. View'de olay işlendiğinde, View yeni birIntentile ViewModel'e bu bayrağı veya alanı sıfırlaması için gönderir. Bu, mantığı karmaşıklaştırabilir ve yanlış işleme veya View'un yeniden oluşturulması durumunda tekrar tetiklenmesine neden olabilir.// Tek kullanımlık bayrak içeren State örneği data class MyUiState( val data: List<Item> = emptyList(), val isLoading: Boolean = false, val showSuccessToast: Boolean = false // Tek kullanımlık olay bayrağı ) // ViewModel'de başarılı işlem sonrası fun processSuccess() { _uiState.update { it.copy(showSuccessToast = true) } } // View'de showSuccessToast = true işlendiğinde if (state.showSuccessToast) { showToast("Başarılı!") // Önemli: Bayrağı sıfırlamak için Intent gönder viewModel.onToastShown() } // ViewModel'de bayrağı sıfırlama fun onToastShown() { _uiState.update { it.copy(showSuccessToast = false) } }
Modern Android'de Flow ve MVI ile en önerilen yaklaşım, Channel aracılığıyla Yan Etkiler kullanmaktır. Bu, tek seferlik olaylar için temiz, güvenli ve öngörülebilir bir çözümdür.