#android #kotlin #kotlin-coroutines
#Android #kotlin #kotlin-сопрограммы
Вопрос:
Сейчас я внедряю MutableStateFlow
сохранение значения кэша в архитектуре Android MVVM. Цель состоит в том, чтобы его можно было получить только в первый раз, чтобы избежать большого количества избыточных сетевых подключений, и его также можно обновлять при необходимости. Поэтому у меня возникают следующие вопросы:
- Как сбросить значение и снова запросить данные выборки в MutableStateFlow с помощью следующего кода?
- Я на неверном пути, чтобы использовать 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
свойство только при его использовании.
Извлечение кэшированных данных должно происходить на верхнем уровне:
- Используйте тот же поток для передачи локальных и сетевых данных
- Установите ограничение, когда извлекать данные из сети; отсутствие локальных данных, временные ограничения и т. Д.
Следующая функция предназначена только для иллюстрации, сначала извлекается из локального хранилища, а затем пытается извлечь из сети, если локальные данные отсутствуют или ограничение выполнено.
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. Вы также можете использовать его реактивным способом, где вы можете связать все это.