我的代码中新版本的 kotlinx-coroutines-play-services 出现问题

Problem with the new version of kotlinx-coroutines-play-services into my code

我已经在我的代码中添加了协程播放服务,发现一切正常,但是在将协程更新到版本 1.3.2 之后,我的应用程序崩溃并给我以下错误,但在堆栈跟踪中是不可能的为了查看我的代码中错误的来源,我尝试使用断点,然后我注意到取消 flowawaitClose {cancel()} 时发生了错误。堆栈跟踪是:

    2021-08-04 09:40:30.976 11200-11200/com.kola.kolaapplication.dev E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.IllegalStateException: 'awaitClose { yourCallbackOrListener.cancel() }' should be used in the end of callbackFlow block.
    Otherwise, a callback/listener may leak in case of external cancellation.
    Process: com.kola.kolaapplication.dev, PID: 11200
    See callbackFlow API documentation for the details.
2021-08-04 09:40:30.976 11200-11200/com.kola.kolaapplication.dev E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.IllegalStateException: 'awaitClose { yourCallbackOrListener.cancel() }' should be used in the end of callbackFlow block.
        at kotlinx.coroutines.flow.CallbackFlowBuilder.collectTo(Builders.kt:362)
    Process: com.kola.kolaapplication.dev, PID: 11200
    Otherwise, a callback/listener may leak in case of external cancellation.
        at kotlinx.coroutines.flow.CallbackFlowBuilder$collectTo.invokeSuspend(Unknown Source:15)
    See callbackFlow API documentation for the details.
    java.lang.IllegalStateException: 'awaitClose { yourCallbackOrListener.cancel() }' should be used in the end of callbackFlow block.
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.flow.CallbackFlowBuilder.collectTo(Builders.kt:362)
    Otherwise, a callback/listener may leak in case of external cancellation.
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
    See callbackFlow API documentation for the details.
        at kotlinx.coroutines.flow.CallbackFlowBuilder$collectTo.invokeSuspend(Unknown Source:15)
        at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:190)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.flow.CallbackFlowBuilder.collectTo(Builders.kt:362)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161)
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
        at kotlinx.coroutines.flow.CallbackFlowBuilder$collectTo.invokeSuspend(Unknown Source:15)
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:398)
        at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:190)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:184)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161)
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
        at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core(CancellableContinuationImpl.kt:191)
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:398)
        at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:190)
        at kotlinx.coroutines.ChildContinuation.invoke(JobSupport.kt:1474)
        at kotlinx.coroutines.CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:184)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:398)
        at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core(CancellableContinuationImpl.kt:191)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.ChildContinuation.invoke(JobSupport.kt:1474)
        at kotlinx.coroutines.CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:184)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core(CancellableContinuationImpl.kt:191)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.ChildContinuation.invoke(JobSupport.kt:1474)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:900)
        at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:863)
        at kotlinx.coroutines.JobSupport.cancelMakeCompleting(JobSupport.kt:696)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:667)
        at kotlinx.coroutines.JobSupport.cancelInternal(JobSupport.kt:632)
        at kotlinx.coroutines.JobSupport.cancel(JobSupport.kt:617)
        at kotlinx.coroutines.JobKt__JobKt.cancel(Job.kt:561)
        at kotlinx.coroutines.JobKt.cancel(Unknown Source:1)
        at kotlinx.coroutines.JobKt__JobKt.cancel$default(Job.kt:560)
        at kotlinx.coroutines.JobKt.cancel$default(Unknown Source:1)
        at androidx.lifecycle.CloseableCoroutineScope.close(ViewModel.kt:51)
        at androidx.lifecycle.ViewModel.closeWithRuntimeException(ViewModel.java:188)
        at androidx.lifecycle.ViewModel.clear(ViewModel.java:134)
        at androidx.lifecycle.ViewModelStore.clear(ViewModelStore.java:62)
        at androidx.fragment.app.FragmentManagerViewModel.clearNonConfigState(FragmentManagerViewModel.java:199)
        at androidx.fragment.app.FragmentStateManager.destroy(FragmentStateManager.java:772)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:350)
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
2021-08-04 09:40:30.980 11200-11200/com.kola.kolaapplication.dev E/AndroidRuntime:     at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3126)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.JobSupport.tryMakeCancelling(JobSupport.kt:795)
        at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:3105)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at androidx.fragment.app.Fragment.performDestroy(Fragment.java:3214)
        at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:755)
        at androidx.fragment.app.FragmentStateManager.destroy(FragmentStateManager.java:774)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:350)
        at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637)
        at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:900)
        at androidx.fragment.app.SpecialEffectsController$FragmentStateManagerOperation.complete(SpecialEffectsController.java:742)
        at androidx.fragment.app.SpecialEffectsController$Operation.cancel(SpecialEffectsController.java:594)
        at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1465)
        at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:863)
        at androidx.fragment.app.SpecialEffectsController.forceCompleteAllOperations(SpecialEffectsController.java:329)
        at kotlinx.coroutines.JobSupport.notifyCancelling(JobSupport.kt:1499)
        at kotlinx.coroutines.JobSupport.cancelMakeCompleting(JobSupport.kt:696)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3130)
        at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:3105)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:667)
        at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:900)
        at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:334)
        at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:330)
        at kotlinx.coroutines.JobSupport.cancelInternal(JobSupport.kt:632)
        at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:863)
        at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:242)
        at android.app.Activity.performDestroy(Activity.java:8865)
        at kotlinx.coroutines.JobSupport.cancel(JobSupport.kt:617)
        at kotlinx.coroutines.JobSupport.cancelMakeCompleting(JobSupport.kt:696)
        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1316)
        at kotlinx.coroutines.JobKt__JobKt.cancel(Job.kt:561)
        at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:667)
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4539)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4572)
        at kotlinx.coroutines.JobKt.cancel(Unknown Source:1)
        at kotlinx.coroutines.JobSupport.cancelInternal(JobSupport.kt:632)
        at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:39)
        at kotlinx.coroutines.JobSupport.cancel(JobSupport.kt:617)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
        at kotlinx.coroutines.JobKt__JobKt.cancel$default(Job.kt:560)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1830)
        at kotlinx.coroutines.JobKt.cancel$default(Unknown Source:1)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at kotlinx.coroutines.JobKt__JobKt.cancel(Job.kt:561)
        at androidx.lifecycle.CloseableCoroutineScope.close(ViewModel.kt:51)
        at android.os.Looper.loop(Looper.java:193)
        at kotlinx.coroutines.JobKt.cancel(Unknown Source:1)
        at android.app.ActivityThread.main(ActivityThread.java:6914)
        at androidx.lifecycle.ViewModel.closeWithRuntimeException(ViewModel.java:188)
        at java.lang.reflect.Method.invoke(Native Method)
        at kotlinx.coroutines.JobKt__JobKt.cancel$default(Job.kt:560)
        at androidx.lifecycle.ViewModel.clear(ViewModel.java:134)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588)
        at kotlinx.coroutines.JobKt.cancel$default(Unknown Source:1)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
        at androidx.lifecycle.ViewModelStore.clear(ViewModelStore.java:62)
        at androidx.lifecycle.CloseableCoroutineScope.close(ViewModel.kt:51)
        at androidx.fragment.app.FragmentManagerViewModel.clearNonConfigState(FragmentManagerViewModel.java:199)

**Coroutine into my gradle file:**
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.2'

我的代码:

val curentUserDocRef: DocumentReference
    get() = firestoreInstance.document(
        commonFireStoreRefKeyWord.USERS_COLLECTION_REF.plus(
            "/${FireStoreAuthUtil.getUserUID()}"
        )
    )

 fun saveUserToFireStore(newUser: KUser): Flow<FirebaseResponseType<KUser>> = callbackFlow{

    curentUserDocRef.get().addOnSuccessListener { documentSnapshot ->
        //Get the user into firebase firestore
        if (!documentSnapshot.exists()) {
           //If the user does not exist, we save it
            curentUserDocRef.set(newUser)
                .addOnSuccessListener {
                    
                try {
                        
                 this.trySend(FirebaseResponseType.FirebaseSuccessResponse(newUser)).isSuccess
                } catch (ex: Exception) {
                   ex.printStackTrace()
                   Log(ex.message)
                   cancel()
                }
        } else {
            // If the user already save, we don't save it anymore
            val userData = documentSnapshot.toObject(KUser::class.java)
            try {
                this.trySend(FirebaseResponseType.FirebaseSuccessResponse(userData)).isSuccess
            } catch (ex: Exception) {
                ex.printStackTrace()
                cLog(ex.message)
                cancel()
            }
        }
    }.addOnFailureListener {
        it.printStackTrace()
        cLog(it.message)
        try {
            this.trySend(FirebaseResponseType.FirebaseErrorResponse(it)).isSuccess
        } catch (ex: Exception) {
            ex.printStackTrace()
            cLog(ex.message)
            printLogD(TAG, ex.message ?: "")
        }
        cancel()
    }

    try {
        awaitClose {
            cancel()  // **I think the error occured here**
        }
    } catch (ex: Exception) {
        ex.printStackTrace()
        cLog(ex.message)
        printLogD(TAG, ex.message ?: "")
    }

}

进入协程播放服务的预览版,我使用的是offer()而不是trySend(),但是进入协程coroutines-play-services:1.3.2,offer()方法被弃用了,他们要求使用 trySend()。

应该怎么做才能解决这个问题拜托,我已经找了一个星期的解决方案

我在 callbackFlow 中将 offer 更改为 trySend 时遇到了同样的问题。

我注意到当我关闭范围而不是通道时我的应用程序崩溃了。

所以为了解决我的问题,我使用 awaitClose { channel.close() } 而不是 awaitClose { cancel() }