How to use MutableStateFlow to save cache in android?

Viewed 1640

I am now implementing MutableStateFlow to store the cache value in Android MVVM architecture . The goal is, it could be fetched only at the first time to avoid much redundant network connection and it could be also updated when needed. Therefore, I have the following questions:

  1. How to reset the value and request fetch data again in the MutableStateFlow with the following code?
  2. Am I on a wrong track to use lazy to save the cache value?

enter image description here

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()
    }
}

Appreciate any comment or advice

1 Answers

Your lazy block will only initialize the cacheWeather property, when you use it.

Fetching the cached data should happen on upper level:

  1. Use the same flow to emit from local and network data
  2. Set constraint when to fetch from network; local data absence, time constraints etc.

Following function is just for illustration, fetches first from local storage then tries to fetch from network if the local data is not present or constraint is met.

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)
    }
} 
Related