I'm using LiveData+Room+ViewModel to build a simple kotlin app. The main activity (which presents a list) is getting the required data from a ViewModel which is getting the info from a database (the data is transformed before being consumed by the activity). Now, I need to allow the user to refresh the data through a swipe. When that happens, the app should check if the current connection can be used for that and if it can't, then the app should schedule a job.
Currently, I'm delegating this work (check the current connection and the eventual job scheduling) to my ViewModel. It looks like this:
fun tryToRefreshDataFromService(){
//first, check if there's network
//If there is, call web service and then update db
//if no network, schedule a job and try to refresh from the database
if(canGetDataFromNetwork()){
Timber.d("With network access, getting data from web services")
WebServiceAsyncTask(newsManager).execute()
}
else{
//schedule job for refreshing
//no network access, setting up job
Timber.d("No network access, setting up job")
scheduleJob()
}
}
The activity will then be able to call the method from within a helper method (which handles the swiper refresh event):
private fun recoverDataForTabs(swiper: SwipeRefreshLayout? = null){
_swiper = swiper //for clearing
_viewModel.tryToRefreshDataFromService()
}
However, it seems like this is really a bad idea because it seems like ViewModels shouldn't know anything about Android framework classes (and that ends up being required for this case). So, does this mean that I should update my code so that the network checking + job scheduling is done from the activity?
Thanks
You can inject framework-related objects into your ViewModels
. For example:
class MyViewModel(val networkChecker: IMyNetworkChecker, val jobSetter: IMyJobSetter, ...) {
fun tryToRefreshDataFromService(){
if(networkChecker.canGetDataFromNetwork()){
Timber.d("With network access, getting data from web services")
WebServiceAsyncTask(newsManager).execute()
}
else{
Timber.d("No network access, setting up job")
jobSetter.scheduleJob()
}
}
}