https://kotlinlang.org logo
#android
Title
# android
g

Gautam Lad

06/05/2019, 2:34 AM
Hey guys, With the new viewModelScope, when it gets cancelled, why doesn’t future launch call do anything?
Copy code
viewModelScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
            contentLiveData.postValue(getDiscoverContentUseCase.execute())
        }
If I put a breakpoint on launch line I see it’s cancelled.
Copy code
viewModelScope = {CloseableCoroutineScope@5985} 
 coroutineContext = {CombinedContext@5986} "[SupervisorJobImpl{Cancelled}@7ed8dea, Main]"
i

itnoles

06/05/2019, 2:36 AM
"A failure of a child job that was created using launch can be handled via CoroutineExceptionHandler in the context."
g

Gautam Lad

06/05/2019, 2:39 AM
Fairly new to this so not sure what that means
i dont see any exceptions or logs indicating something had failed
i

itnoles

06/05/2019, 2:40 AM
I think you are not really catching it.
g

Gautam Lad

06/05/2019, 2:44 AM
Are you saying something inside the launch { } is failing?
i

itnoles

06/05/2019, 2:44 AM
yeah
g

Gautam Lad

06/05/2019, 2:45 AM
I did something like:
Copy code
viewModelScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
            Log.i(TAG, "Inside launch")
         }
And it’s not getting to the Log statement
i

itnoles

06/05/2019, 2:45 AM
try without (Dispatchers.IO)
g

Gautam Lad

06/05/2019, 2:45 AM
I am switching between fragments (where one of hte fragment has the viewmodel) and if the fragment is created/destroyed fast the viewmodel enters a cancelled state
ok will try
Same thing:
Copy code
viewModelScope = {CloseableCoroutineScope@5902} 
 coroutineContext = {CombinedContext@5929} "[SupervisorJobImpl{Cancelled}@e3d3400, Main]"
Also tried:
Copy code
val handler = CoroutineExceptionHandler { _, exception ->
            Log.e(TAG, "Error $exception", exception)
        }
        viewModelScope.launch(handler) {
And not getting the log
l

liemvo

06/05/2019, 3:05 AM
viewModelScope
is belonged to the
ViewModel
so it will cancel the future launch when you switch fragments quickly
g

Gautam Lad

06/05/2019, 3:11 AM
so once a scope is cancelled there’s no way to restart it?
l

liemvo

06/05/2019, 3:16 AM
It depends on your ViewModel
g

Gautam Lad

06/05/2019, 3:17 AM
it’s the same viewmodel instance
the fragment is destroyed and re-created
l

liemvo

06/05/2019, 3:18 AM
Your ViewModel should belong to the activity???
g

Gautam Lad

06/05/2019, 3:19 AM
it does
in the fragment it’s
viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(MyViewModel::class.java)
m

Melih Aksoy

06/05/2019, 8:24 AM
Where do you call launch ? You sure you’re calling that function to start it ?
g

Gautam Lad

06/05/2019, 11:14 AM
The call is made in onviewcreated and it's called since i can reach breakpoint on launch line.
It just never enters the inside of lsuch block since the scope is cancelled as I posted
Isuch =launch
m

Melih Aksoy

06/05/2019, 11:32 AM
hmm, I also use viewModelScope but didn’t encounter this issue so far. Sounds more like a lifecycle issue. ViewModel should be cancelling this scope in
onCleared
method. Overriding and debugging it might reveal the reason
That might be a clue
m

Melih Aksoy

06/05/2019, 12:03 PM
Yes indeed.
cancel
is called in
ViewModel.kt
for
viewModelScope
. Did you hit
onCleared
in debugging ?
g

Gautam Lad

06/05/2019, 12:33 PM
Yup I did
m

Melih Aksoy

06/05/2019, 1:07 PM
Based on your previous snippets, you’re sharing this viewmodel by using activity lifecycle right ? Didn’t really debug similar situation, but it seems viewModel gets cleared, but not destroyed, and doesn’t re-create the coroutine scope 🤔
g

Gautam Lad

06/05/2019, 3:10 PM
Yeah the activity hasn't changed
I'm actually making a leanback TV app
And I have one activity and one fragment.. Inside the fragment I have a tab system that changed pages (child fragment manager transactions)
When I change tabs I replace the (child) fragment
So the child fragment rely on view model that gets a cleared event and subsequently the scope is set to cancelled
I might just have to use my own scope and job cancelations on clear or on repetitive load calls
m

Melih Aksoy

06/06/2019, 8:39 AM
Seems like a solution,
cancelChildren
instead of
cancel
in
onCleared
. Wonder what causes VM to clear and cancel it’s scope. Would be nice to update here if you find out !
119 Views