ViewModel: Check if fragment is resume or stop

Viewed 2126

I perform network stuff inside ViewModel that repeat its fetching with interval of 10 seconds with RxJava. However I do not want to fetch data from this API when my Fragment is not visible to screen for example is when I opened an Activity on a top of it I will have a code like if(!isResume) return. My question will be, is it okay to use a MutableLiveData<Boolean> where value will be updated in onResume and onPause so I can just ignore network request if not resume or is it against the concept of MVVM? We can do this but not sure if it is okay to do so.

2 Answers

You can make your ViewModel implement the interface DefaultLifecycleObserver (https://developer.android.com/reference/androidx/lifecycle/DefaultLifecycleObserver), and then you override the methods onResume and onPause. Update an internal boolean variable, e.g. isResumed, when those methods are called and you'll be able to check in other methods if the corresponding fragment is on the resumed state.

class YourViewModel : DefaultLifecycleObserver {
    private var isResumed = false

    override fun onResume(owner: LifecycleOwner) {
        isResumed = true
    }

    override fun onPause(owner: LifecycleOwner) {
        isResumed = false
    }
}

You also need to update your Fragment code to add that ViewModel as a lifecycle observer:

class YourFragment : Fragment() {
    private val viewModel: YourViewModel // initialize it

    override fun onViewCreated(...) {
        lifecycle.addObserver(viewModel)
    }
}

I wouldn't want my ViewModel to know about the View's lifecycle, since it's conceptually wrong I think. If your ViewModel at some point gets shared between multiple Views, which one will stop the fetching?

You'd need a logic in that case, that is tied to the number of subscribers instead, and manage the subscriptions in your View. Hopefully there are solutions for that:

  1. Use an RxJava implementation instead of LiveDatas, which stops execution when there are no subscribers, remove subscribers manually in onPause
  2. ** Use Kotlin Flows, read this article. You could expose a Flow, with SharingStarted.WhileSubscribed and collect it with
flowWithLifecycle(lifecycleOwner, Lifecycle.State.RESUMED)
Related