Я сейчас изучаю, как использовать сопрограммы Kotlin для приложений Android. И одна из вещей, которые меня очень привлекают, это возможность синхронно обрабатывать асинхронные процедуры.
Итак, мое игрушечное приложение основано на архитектуре MVVM и использует Firebase для реализации функций входа / выхода. И есть вариант использования SignOut:
class FirebaseSignOut @Inject constructor(private val firebaseAuthUi: AuthUI) : SignOut {
private lateinit var signOutResult: SignOutResult
override fun execute(context: Context): SignOutResult {
runBlocking {
signOutResult = getSignOutResult(context)
}
return signOutResult
}
private suspend fun getSignOutResult(context: Context): SignOutResult {
return suspendCoroutine { continuation ->
firebaseAuthUi.signOut(context)
.addOnSuccessListener {
continuation.resume(SignOutSuccess)
}
.addOnFailureListener {
continuation.resume(SignOutError)
}
.addOnCanceledListener {
continuation.resume(SignOutCancel)
}
}
}
}
Проблема
означает, что блокировка, запущенная с помощью runBlocking, никогда не разблокируется.
Я выяснил, что сама логика сопрограмм не является проблемой, заменив getSignOutResult () на mock, например:
private suspend fun getSignOutResult(context: Context): SignOutResult {
delay(500)
return SignOutError
}
Тогда я смог отследить блокировку до этой части AuthUI Firebase:
return Tasks.whenAll(
signOutIdps(context),
maybeDisableAutoSignIn
).continueWith(new Continuation<Void, Void>() {
https://github.com/firebase/FirebaseUI-Android/blob/master/auth/src/main/java/com/firebase/ui/auth/AuthUI.java#L325
private Task<Void> signOutIdps(@NonNull Context context) {
...
return GoogleSignIn.getClient(context, GoogleSignInOptions.DEFAULT_SIGN_IN).signOut();
}
https://github.com/firebase/FirebaseUI-Android/blob/master/auth/src/main/java/com/firebase/ui/auth/AuthUI.java#L403
и выясните, что может быть DisableAutoSignIn Task никогда не запускается. Итак, тупик, возникающий где-то внутри signOut () GoogleSignIn, который не может отследить.
Вопрос
У кого-нибудь есть идея, почему такой тупик может случиться? И любое предложение, как решить проблему, очень приветствуется.
Подробности конфигурации
Я использую последние версии библиотек Kotlin и Firebase
firebaseCoreVersion = '16.0.4'
firebaseUiVersion = '4.1.0'
kotlinVersion = '1.3.0'
kotlinCoroutinesVersion = '1.0.0'
AuthUI разрешил использовать только вход в Google.
! ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ , что я знаю, что я могу сделать переменную signOutResult наблюдаемой. Но в этом случае execute не сможет вернуть результат. И я действительно хочу это сделать, потому что такая реализация легко поддается проверке. И тот факт, что runBlocking блокирует основной поток для выхода, является приемлемым в моем случае - имеет смысл, что пользовательский интерфейс недоступен во время процедуры, поскольку пользовательский интерфейс значительно изменяется в зависимости от состояния аутентификации.