Как использовать MutableStateFlow для сохранения кэша в Android?

#android #kotlin #kotlin-coroutines

#Android #kotlin #kotlin-сопрограммы

Вопрос:

Сейчас я внедряю MutableStateFlow сохранение значения кэша в архитектуре Android MVVM. Цель состоит в том, чтобы его можно было получить только в первый раз, чтобы избежать большого количества избыточных сетевых подключений, и его также можно обновлять при необходимости. Поэтому у меня возникают следующие вопросы:

  1. Как сбросить значение и снова запросить данные выборки в MutableStateFlow с помощью следующего кода?
  2. Я на неверном пути, чтобы использовать lazy для сохранения значения кэша?

введите описание изображения здесь

 class WeatherRepository {
    private val mDefaultDispatcher: IDefaultDispatcher by inject()
    private val scope by lazy { CoroutineScope(mDefaultDispatcher.io()   SupervisorJob()) }
    val cacheWeather by lazy {
        val flow = MutableStateFlow<List<Weather>?>(null)
        scope.launch(mDefaultDispatcher.io()) {
            val response = getWeather()
            if (response.isValid) {
                val data = response.data
                flow.value = data
            }
        }
        flow
    }
}
 
 class ViewModelA {
    private val mRepository: WeatherRepository by inject()
    val weather by lazy {
        mRepository.cacheWeather.asLiveData()
    }

    fun requestUpdateOnWeather() {
       //TODO (dunno how to make the mutableStateFlow reset and fetch data again)
    }
}
 
 class ViewModelB {
    private val mRepository: WeatherRepository by inject()
    val weather by lazy {
        mRepository.cacheWeather.asLiveData()
    }
}
 

Цените любые комментарии или советы

Ответ №1:

Ваш ленивый блок будет инициализировать cacheWeather свойство только при его использовании.

Извлечение кэшированных данных должно происходить на верхнем уровне:

  1. Используйте тот же поток для передачи локальных и сетевых данных
  2. Установите ограничение, когда извлекать данные из сети; отсутствие локальных данных, временные ограничения и т. Д.

Следующая функция предназначена только для иллюстрации, сначала извлекается из локального хранилища, а затем пытается извлечь из сети, если локальные данные отсутствуют или ограничение выполнено.

 val flow = MutableFlow<Data>(Data.empty())
fun fetchData() = coroutinesScope.launch {
    val localData = getLocalData()
    if(localData.isDataPresent()) {
        flow.emit(localData)
    }
    if (willFetchFromNetwork()) {
        val networkData = getNetwork()
        flow.emit(networkData)
        cacheData(networkData)
    }
} 
 

Комментарии:

1. Значит, MutableStateFlow будет отвечать только за передачу значения? Ваше решение выглядит хорошо и обладает большей гибкостью для добавления ограничений

2. Вы также можете использовать его реактивным способом, где вы можете связать все это.