Home > Blockchain >  LiveData not firing when Inside Network Change Callbacks in Android View Model - Kotlin
LiveData not firing when Inside Network Change Callbacks in Android View Model - Kotlin

Time:11-16

Trying to listen to a Connection call back using Live Data. The Callbacks "onAvailable" and "onLost" are fired, but the "postValue" inside the ViewModel is not fired. It is first only once when the AppViewModel is initialized and the init is called only once. When I move the postData outside the network callbacks, it fires. Any help is appreciated.

class AppViewModel(application: Application) : AndroidViewModel(application) {

    private var connectivityManager =
        application.applicationContext.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    var wifiStatusListener = MutableLiveData<Boolean>()

    var callback: NetworkCallback =
        object : NetworkCallback() {
            override fun onAvailable(network: Network) {
                wifiStatusListener.postValue(true) // never calls.
                logI(TAG, "onAvailable ${network.describeContents()}")
            }

            override fun onLost(network: Network) {
                wifiStatusListener.postValue(false) // never calls.
                logE(TAG, "onLost ${network.describeContents()}")
            }
        }



    init {
        logI(TAG, "View Model Initialized")
        viewModelScope.launch {
            initWiFiStatusCheckListener()
        }
    }
 // called from init in ViewModel
 connectivityManager.registerDefaultNetworkCallback(callback)

In Activity, this is how View model is initialized. The log below is called only once for the first time

logI(TAG, "Wifi Listener $it")
 appViewModel = ViewModelProvider(this).get(AppViewModel::class.java)
 appViewModel.wifiStatusListener.observe(this, Observer {
            logI(TAG, "Wifi Listener $it")
        })     

CodePudding user response:

You should observe the change of connectivity in Activity or Fragment. Then in each call back for the changes, you pass your callback from ViewModel to handle this. And you don't need to use the wifiStatusListener to observe change. Just get the property inside the callback to handle.

Notice that you should not pass the application context to the ViewModel. Just use current context in the Activity.

CodePudding user response:

If your ViewModel is using Context in any form I typically make the ViewModel follow along the AndroidLifeCycle instead of storing Context in the ViewModel.

//in ViewModel
fun onResume(context : Context){
    var connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    connectivityManager.registerDefaultNetworkCallback(callback)
}
fun onPause(context : Context){
    var connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    connectivityManager.unregisterNetworkCallback(callback)
}



//in Activity/Fragment
fun onResume(){
    super.onResume();
    viewModel.onResume(requireContext())
}
fun onPause(){
    viewModel.onPause(requireContext())
    super.onPause();
}

You could also store the ConnectivityManager in the Activity/Fragment and just pass it instead of context but don't store it in the ViewModel.

  • Related