SKREFI
SKREFI

Reputation: 187

Can I get the context inside ViewModel's init block?

I am implementing offline mode for my application, my plan is to put the local db between the UI and API Requests.

I have this fragment and his viewmodel with this init block:

init {
   viewModelScope.launch(Dispatchers.IO) {
      // context required here
      loadVehicles()
   }
}

Now, inside loadVehicles, I want to check if I am online or not, if I am, I will simply make a call to the API to update my local database in case there is anything new.

fun isOnline(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (connectivityManager != null) {
        val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (capabilities != null) {
            return true
        }
    }
    return false
}

This was the simplest code I could find to test if I am online or not, and this function needs the context, which is unaccessable from the init block of the view model.

Looking forward hearing other suggestions of doing things if there is something I can improve with mine.

Upvotes: 2

Views: 4599

Answers (1)

Yavor Mitev
Yavor Mitev

Reputation: 1508

Your code "must" look like this:

class SomeHelperClass @Inject constructor(private val  context: Context) {

    fun isOnline(): Boolean {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (connectivityManager != null) {
            val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
            if (capabilities != null) {
                return true
            }
        }
        return false
    }
}


class MyViewModel @Inject constructor(helper: SomeHelperClass):ViewModel()  {
    init {
        viewModelScope.launch(Dispatchers.IO) {

            // call to helper.isOnline() !!!!!!

            loadVehicles()
        }
    }
}
  • That is how the code in MyViewModel will not dependent on the Context, which means no instrumental tests are needed. You can test it with plain Kotlin/Java tests.

  • I know that you might not want to test it, but one of the good results of testing is that it makes the code better. If you make testable code it will be better even if you do not test it. And in this case, you are not making heavy ViewModels which is a bad idea.

  • Also, I am suggesting you to use Dagger-Hilt if you are not using it already - @Inject

Upvotes: 3

Related Questions