Проблема с новой версией 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() }
.