Thread
#compose
    b

    Bradleycorn

    1 year ago
    Some questions around
    navigation-compose
    and ViewModels. For a time now, we've been able to get a viewmodel scoped to a backstack entry (at first by rolling our own factory, then using a HiltViewModelFactory, and now by using
    hiltNavGraphViewModel()
    ). I presume that means that as long as the backstack entry exists, then the VeiwModel will hang around, and won't be cleared until the backstack entry is popped, right? And if so, you might need to be careful in some cases when launching a coroutine using
    viewModelScope.launch
    , right? If your are just making a newtork call to fetch a piece of data or something, no big deal. But if it's a longer running operation, then it will not get canceled until the backstackentry is popped from the stack. So, if say you have Composables A, B, and C that are entries in your graph, and you navigate from A to B to C ... if the ViewModel for A launched a coroutine in its
    viewModelScope
    , it will still be running while the user is looking at C, correct? So if your intention is to launch a coroutine when the user is looking at A and have it get canceled when the user navigates to B, then you really need to use a different mechanism (like say
    LaunchedEffect
    ). Do I have that right?
    i

    Ian Lake

    1 year ago
    The
    viewModelScope
    survives for the entire time the destination is on the back stack and would not be affected by navigating to a new destination, correct. It will be cancelled when you pop the destination off the back stack, also correct.
    b

    Bradleycorn

    1 year ago
    Thanks @Ian Lake that's what I thought. Just wanted to make sure I had my use cases straight in my head.
    a

    allan.conda

    1 year ago
    not sure we should be using LaunchedEffect for that though, your ViewModel could listen to navigation events and cancel the launch
    i

    Ian Lake

    1 year ago
    Your ViewModel shouldn't have any references to your composable, etc., so listening for events is not the approach you should use. However, your ViewModel could certainly offer a
    suspend
    method that you call within a
    LaunchedEffect
    - that would cancel quite nicely when you navigate
    k

    KamilH

    1 year ago
    Isn’t there any general way to have ViewModel scoped to
    Composable
    ?
    i

    Ian Lake

    1 year ago
    No, the only scoping available right now is via Navigation Compose. Being able to scope ViewModels to any Composable is being tracked in https://issuetracker.google.com/issues/165642391
    b

    Bradleycorn

    1 year ago
    yeah, the idea in my original post gets at what @Ian Lake is saying. I have a few places where I have to poll a network api every so often, and I only want that polling to run while the user is on the "Screen" composable that uses that data (so I don't waste their battery and data plan to poll for something they aren't even looking at). ... So my ViewModel has a
    suspend
    method that does the polling, and I call it from a
    LaunchedEffect
    in the "Screen" composable, and thus it gets canceled when the user navigates to a "child screen", stopping the polling.
    i

    Ian Lake

    1 year ago
    Yep, there's some more stuff coming out in the next Lifecycle release that will help with handling flow collection in other cases (like hitting the system home button): https://kotlinlang.slack.com/archives/CJLTWPH7S/p1615397085281600?thread_ts=1615395535.277500&cid=CJLTWPH7S
    b

    Bradleycorn

    1 year ago
    yep. good points in the above RE: the coroutine launched via
    LaunchedEffect
    remains active if the app goes to the background. I work hack around it by using the lifecycleScope of the containing activity, but I'm looking forward to a better solution.
    i

    Ian Lake

    1 year ago
    Yeah, this new API seems like it will be a good fit for that