Проблема с новой версией kotlinx-coroutines-play-services в моем коде

Я уже добавил сервисы воспроизведения сопрограмм в свой код, все работало, найти, но после обновления сопрограмм до версии 1.3.2 мое приложение вылетало и вызывало ошибку, указанную ниже, но в трассировке стека невозможно увидеть происхождение ошибка в моем коде, я попытался использовать точки разрыва, а затем замечаю, что произошла ошибка при отмене потока awaitClose {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$1.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$1.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$1.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 ().

Что нужно сделать для решения этой проблемы Прошу, уже неделю ищу решение

1 ответ

Решение

У меня была такая же проблема, когда я меняю предложение с помощью trySend в моем callbackFlow.

Я замечаю, что когда я закрываю область действия вместо канала, мое приложение вылетает.

Итак, чтобы решить свою проблему, я использовал awaitClose { channel.close() } вместо awaitClose { cancel() }.

Другие вопросы по тегам