CancellableContinuation 的 invokeOnCancellation 处理程序中出现异常

Exception in invokeOnCancellation handler for CancellableContinuation

我有一个 suspendCancellableCoroutine 作为动画侦听器扩展,但它在 api 30 时崩溃,这是扩展

suspend fun Animator.startAndWait() = suspendCancellableCoroutine<Unit> { continuation ->

    continuation.invokeOnCancellation { cancel() }

    this.addListener(object : AnimatorListenerAdapter() {

        private var endedSuccessfully = true

        override fun onAnimationCancel(animation: Animator?) {
            endedSuccessfully = false
        }

        override fun onAnimationStart(animation: Animator?) {

            animation?.removeListener(this)

            if (continuation.isActive) {
                // If the coroutine is still active...
                if (endedSuccessfully) {
                    // ...and the Animator ended successfully, resume the coroutine
                    continuation.resume(Unit)
                } else {
                    // ...and the Animator was cancelled, cancel the coroutine too
                    continuation.cancel()
                }
            }
        }
    })
    start()
}

我是从另一个动画师的 运行 方法中调用它的

private fun createRevealAnimation() {
    val x: Int = binding.root.right / 2
    val y: Int = binding.root.bottom - binding.root.bottom / 9
    val endRadius = hypot(binding.root.width.toDouble(), binding.root.height.toDouble()).toInt()
    viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) {
        createCircleRevealAnimator(x, y, endRadius).run {
            duration = 250
            withContext(Dispatchers.Main){
                binding.pokeballOpen.visibility = View.VISIBLE
            }
            startAndWait()
            navigateToListFragment()
        }
    }
}

private fun createCircleRevealAnimator(x: Int, y: Int, endRadius: Int): Animator {
    return ViewAnimationUtils.createCircularReveal(
        binding.pokeballOpen, x, y,
        0f,
        endRadius.toFloat()
    )
}

在 api 30 之前它在每个版本上都运行良好,然后崩溃并抛出此错误

    2021-02-06 17:50:42.205 29495-29590/com.sealstudios.pokemonApp.paid E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
    Process: com.sealstudios.pokemonApp.paid, PID: 29495
    kotlinx.coroutines.CompletionHandlerException: Exception in invokeOnCancellation handler for CancellableContinuation(DispatchedContinuation[Dispatchers.Default, Continuation at com.sealstudios.pokemonApp.ui.SplashScreenFragment$createRevealAnimation.invokeSuspend(SplashScreenFragment.kt:61)@472a1ed]){CancelledContinuation[kotlinx.coroutines.JobCancellationException: StandaloneCoroutine is cancelling; job=StandaloneCoroutine{Cancelling}@c735822]}@e4312b3
    at kotlinx.coroutines.CancellableContinuationImpl.callCancelHandler(CancellableContinuationImpl.kt:583)
    at kotlinx.coroutines.CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:195)
    at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core(CancellableContinuationImpl.kt:205)
    at kotlinx.coroutines.ChildContinuation.invoke(JobSupport.kt:1484)
    at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1511)
    at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:897)
    at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:860)
    at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:825)
    at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:111)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
    Caused by: java.lang.IllegalStateException: The current thread must have a looper!
    at android.view.Choreographer.initialValue(Choreographer.java:111)
    at android.view.Choreographer.initialValue(Choreographer.java:106)
    at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180)
    at java.lang.ThreadLocal.get(ThreadLocal.java:170)
    at android.view.Choreographer.getInstance(Choreographer.java:288)
    at android.graphics.animation.RenderNodeAnimator$DelayedAnimationHelper.<init>(RenderNodeAnimator.java:431)
    at android.graphics.animation.RenderNodeAnimator.getHelper(RenderNodeAnimator.java:415)
    at android.graphics.animation.RenderNodeAnimator.cancel(RenderNodeAnimator.java:226)
    at com.sealstudios.pokemonApp.ui.listenerExtensions.AnimatorListenersKt$startAndWait$$inlined$suspendCancellableCoroutine$lambda.invoke(AnimatorListeners.kt:12)
    at com.sealstudios.pokemonApp.ui.listenerExtensions.AnimatorListenersKt$startAndWait$$inlined$suspendCancellableCoroutine$lambda.invoke(Unknown Source:2)
    at kotlinx.coroutines.InvokeOnCancel.invoke(CancellableContinuationImpl.kt:539)
    at kotlinx.coroutines.CancellableContinuationImpl.callCancelHandler(CancellableContinuationImpl.kt:230)
    at kotlinx.coroutines.CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:195) 
    at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core(CancellableContinuationImpl.kt:205) 
    at kotlinx.coroutines.ChildContinuation.invoke(JobSupport.kt:1484) 
    at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1511) 
    at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:897) 
    at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:860) 
    at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:825) 
    at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:111) 
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) 
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665) 

任何人都有任何想法我对这个很迷茫。

删除Dispatchers.Default

viewLifecycleOwner.lifecycleScope.launch { ... }