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
.