I am getting quite a bit of fatal crash reports in Crashlytics, which seems to be caused by a coroutine cancelling. And I have no idea on how to remedy it, and have been unable to reproduce it.
The error in Crashlytics is:
Fatal Exception: java.lang.RuntimeException: Unable to destroy activity {...ui.main.MainActivity}: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelled}@1ad5bcf
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4682)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4700)
at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:39)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
and
Caused by kotlinx.coroutines.JobCancellationException: Job was cancelled
My MainActivity doesn't SupervisorJob, but all my Fragment's extend a base class that has a SupervisorJob. The base fragment also calls SupervisorJob.cancelChildren() in the onStop method.
Any ideas on how to solve this? Or even how to gather more information about where/why it's happening? I haven't been able to reproduce it myself, but it is happening quite a bit in the field.
Unable to destroy activity is telling you that the onDestory method cannot finish.
Caused by kotlinx.coroutines.JobCancellationException: Job was cancelled is telling you that you are interacting with a job but shouldn't be because it was cancelled.
Rather than using SupervisorJob.cancelChildren() you should rely on structured concurrency, instead. Meaning that every one of your jobs should be launched from a scope that is cancelled when your activity or fragment are destroyed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With