Nat Strangerweather
12/26/2022, 5:54 PMsearchJob
every time my search parameter changed in the example below. What happens is that the searchJob
is called successfully the first time I pass my parameter, but never again after that. Could someone please have a look ?fun onSearch(searchTitle: String) {
_searchTitle.value = searchTitle
println("on search started")
searchJob = viewModelScope.launch {
delay(1000L)
println("search job started")
getFeeds(searchTitle)
.onEach { result ->
when (result) {
is Resource.Success -> {
_isRefreshing.value = false
_state.value = state.value.copy(
newsFeedItems = result.data ?: emptyList(),
isLoading = false,
isSuccess = true,
isError = false
)
println("is success") }
onSearch()
function starts, but the searchJob
function does not.Josh Eldridge
12/26/2022, 7:48 PMsearchJob
variable outside of this?Nat Strangerweather
12/26/2022, 8:01 PMJosh Eldridge
12/26/2022, 8:07 PMsearchJob
and only assign it here?
You might want to launch the coroutine with an Coroutine exception handler passed into it to see if there is a hidden exception cancelling the coroutineNat Strangerweather
12/26/2022, 8:10 PMprivate var searchJob: Job? = null
I have been using a tutorial and adapting it to my own project...
I'll do what you suggest. So does it mean that the searchJob needs to be cancelled properly in order to be reused?Josh Eldridge
12/26/2022, 8:13 PMNat Strangerweather
12/26/2022, 8:14 PMJosh Eldridge
12/26/2022, 8:15 PMNat Strangerweather
12/26/2022, 8:16 PMbezrukov
12/26/2022, 8:18 PMvar searchJob: Job? = null
searchJob = viewModelScope.launch {
println("A: before delay")
delay(1000)
println("A: before delay")
}
searchJob = viewModelScope.launch {
println("B: before delay")
delay(1000)
println("B: before delay")
}
I'm pretty sure when you will minimize your case to what I wrote above you should be able to find the cause.Nat Strangerweather
12/26/2022, 8:25 PMfun onSearch(searchTitle: String) {
_searchTitle.value = searchTitle
println("on search started")
searchJob = viewModelScope.launch {
delay(1000L)
println("search job started")
getFeeds(searchTitle)
.onEach { result ->
when (result) {
is Resource.Success -> {
_isRefreshing.value = false
_state.value = state.value.copy(
newsFeedItems = result.data ?: emptyList(),
isLoading = false,
isSuccess = true,
isError = false
)
println("is success")
}
is Resource.Error -> {
_isRefreshing.value = false
_state.value = state.value.copy(
newsFeedItems = result.data ?: emptyList(),
isLoading = false,
isSuccess = false,
isError = true
)
}
is Resource.Loading -> {
_isRefreshing.value = true
_state.value = state.value.copy(
newsFeedItems = result.data ?: emptyList(),
isLoading = true,
isSuccess = false,
isError = false
)
}
}
}.launchIn(this)
}
}
A: before delay
B: before delay
A: after delay
B: after delay
Clear
But only the first time. I assume my problem is elsewhere then. I'll keep investigating.bezrukov
12/26/2022, 8:47 PMviewModelScope
normal androidx' scope? If no (e.g. if it's manually created), that might happen if you have an unhandled exception somewhere.
You can change
println("on search started")
to
println("on search started ${viewModelScope.coroutineContext.job.isActive}")
to check if VM is somehow cancelled second timeNat Strangerweather
12/26/2022, 8:51 PMandroidx.lifecycle.viewModelScope
The result of
println("on search started ${viewModelScope.coroutineContext.job.isActive}")
is "True" the first time and "False" the second time.viewModelScope
can interfere? Because I have a function just before using viewModelScope
too.viewModelScope
with GlobalScope
means my app is working as expected. However, I believe GlobalScope is not recommended, right?bezrukov
12/26/2022, 9:12 PMNat Strangerweather
12/26/2022, 9:14 PM