-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[ ScopedActivity ] Job was cancelled #1649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Here is the behavior I described and should work as expected but it does not work in my android app |
Do you have stacktraces from those crashes? Without that and seeing all your actual code it's impossible to say what's actually crashing. The only thing that looks potentially problematic in your code is that you require all |
Unrelated to correctness, but it's also worth noting that it's no longer considered idiomatic to make activities implement |
@zach-klippenstein thank you for your answer ! I changed my ScopedActivity as you said to not pass the handler to all my abstract class ScopedActivity : BaseActivity(), CoroutineScope {
private val errorHandler = CoroutineExceptionHandler { _, throwable -> onError(throwable) }
override val coroutineContext: CoroutineContext = Dispatchers.Main + SupervisorJob() + errorHandler
open fun onError(e: Throwable? = null) {
e ?: return
Timber.i(e)
}
override fun onDestroy() {
super.onDestroy()
cancel()
}
} For the stacktrace what I get is really not useful, here it is in full :
Concerning your first point about seeing the whole code, what do you need ? The activity extends ScopedActivity, launch a coroutine with a flow collection in it. The flow observe the firebase user auth status combine with the observation of a firebase node with the lib I made FlowFirebase. Concerning your second point about using a private scope property, I do not see the gain, It will work exactly the same and will be cancelled in the |
So it seems that is was related to #1177 and big thanks to @nickallendev for the /**
* Terminal flow operator that collects the given flow with a provided [action] only if the parent [coroutineContext]
* is active
*/
suspend inline fun <T> Flow<T>.collectWhileActive(crossinline action: suspend (value: T) -> Unit): Unit =
collect { value ->
if (coroutineContext.isActive) {
action(value)
}
}
/**
* Terminal flow operator that [launches][launch] the [collection][collect] of the given flow in the [scope] only if
* the parent [coroutineContext] is active
* It is a shorthand for `scope.launch { flow.collectWhileActive {} }`.
*/
fun <T> Flow<T>.launchInWhileActive(scope: CoroutineScope) = scope.launch {
this@launchInWhileActive.collectWhileActive { /* Do nothing */ }
} |
Making your class implement |
@zach-klippenstein thank you I already did what you said and implement a custom scope that also extend lifecycleObserver to cancel the scope in onStop or onDestroy automatically. |
I implemented the ScopedActivity like described here with a CoroutineExceptionHandler like this :
And of course my activities inherit of ScopedActivity and launch coroutines like this :
So all exceptions are catched and I just have to override the onError method to manage errors and retry what I want.
The issue is that my users are experiencing random crashes I cannot reproduce and the only information I get is : "Job was cancelled".
So how can I spot where that exception comes from ? Is it Flow related or not ? Am I doing it wrong?
More code is available here stackoverflow link
The text was updated successfully, but these errors were encountered: