Search code examples
androidandroid-livedataandroid-viewmodel

Android: Where to schedule a job?


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


Solution

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