'ViewModel doesn't update ui after Activity and Fragment was created second time
I have an app which is opened/started from outside via PWA. Then data is fetched from a service and passed to the UI via a Shared ViewModel. When I start the app for the first time it's working fine. When I start it again, ui will not be updated anymore, even if I receive tracking informations. My guess is that it is because the app is destroyed and re-created. However, the .observe is also reassigned so it should workout.
In Fragment
private val locationUpdateViewModel: LocationUpdateViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
locationUpdateViewModel.uiElapsedTime.observe(viewLifecycleOwner) { elapsedTime ->
updateElapsedTime(elapsedTime)
}
startTracking()
}
In ViewModel
val uiElapsedTime: MutableLiveData<String> = MutableLiveData()
fun locationReceived(){
...
uiElapsedTime.postValue("$time")
}
Unfortunately moving startTracking() or Observing to onStart() or onResume() didn't help. I added different logs of every lifecycle process. Attached you can see two things i did.
- When switching to another app and back = WORKING
2022-03-18 10:30:27.168 16851-16851/de.locations D/TAG: Activity onRestart
2022-03-18 10:30:27.197 16851-16851/de.locations D/TAG: TrackDetailLiveFragment onCreate
2022-03-18 10:30:27.430 16851-16851/de.locations D/TAG: Service is running: true
2022-03-18 10:30:28.002 16851-16851/de.locations D/TAG: TrackDetailLiveFragment onResume
2022-03-18 10:30:28.002 16851-16851/de.locations D/TAG: locationUpdateViewModel.loadActiveTrackData()
2022-03-18 10:30:47.540 17461-17461/de.locations D/TAG: BroadcastReceiver onReceive
2022-03-18 10:30:47.543 17461-17461/de.locations D/TAG VIEMODEL: speed 132.79279558118925 distance 404.7006743398197 totalDistance 0.81766925647099 elapsedTime 18 syncWithAPI false
- When opening app again via pwa = NOT WORKING
2022-03-18 10:36:37.517 17461-17461/de.locations D/TAG: Activity destroyed
2022-03-18 10:36:37.609 17461-17461/de.locations D/TAG: TrackDetailLiveFragment onDestroy
2022-03-18 10:36:38.150 17461-17461/de.locations D/TAG: Activity onCreate
2022-03-18 10:36:38.211 17461-17461/de.locations D/TAG: TrackDetailLiveFragment onCreate
2022-03-18 10:36:38.312 17461-17461/de.locations D/TAG: Service is running: true
2022-03-18 10:36:38.594 17461-17461/de.locations D/TAG: TrackDetailLiveFragment onStart
2022-03-18 10:36:38.608 17461-17461/de.locations D/TAG: TrackDetailLiveFragment onResume
2022-03-18 10:36:38.608 17461-17461/de.locations D/TAG: locationUpdateViewModel.loadActiveTrackData()
2022-03-18 10:36:47.540 17461-17461/de.locations D/TAG: BroadcastReceiver onReceive
2022-03-18 10:36:47.543 17461-17461/de.locations D/TAG VIEMODEL: speed 133.79279505888925 distance 401.7009233398197 totalDistance 0.81762263647099 elapsedTime 22 syncWithAPI false
Solution 1:[1]
I think when the app starts again, the Activity or Fragment is not recreated. Because when it first time starts, it works.
According to your code, I think your fragment must not recreate, if your fragment is resued, we should in the OnActivityCreate to restore the data, Because the fragment is not created when it is resued, so the onViewCreate
the method will not be called in that situation.
At the same time, the observer should only add the onCreate method to avoid adding it many times.
so move the startTracking() method to onResume or onActivityCreate
Solution 2:[2]
After days i found the problem and solution. (Re)-creating the fragment and updating viewmodel worked as it should. The problem was, that i used the "old" BroadcastReveiver. I use a Service to receive location updates any my BroadcastReceiver listens for changes. I had to unregister and register again.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Manuel Wenner |
