首页 > 解决方案 > Cooutin 执行任务

问题描述

嗨,这是我的用户存储库

class UserRepository(private val appAuth: FirebaseAuth) : SafeAuthRequest(){

  suspend fun userLogin(email: String,password: String) : AuthResult{
     return authRequest { appAuth.signInWithEmailAndPassword(email,password)}
  }
}

这是 SafeAuthRequest 类

open class SafeAuthRequest {
  suspend fun<T: Any> authRequest(call : suspend () -> Task<T>) : T{

    val task = call.invoke()
    if(task.isSuccessful){
        return task.result!!
    }
    else{
        val error = task.exception?.message
        throw AuthExceptions("$error\nInvalid email or password")
    }
  }
}

调用类似的东西

  /** Method to perform login operation with custom  */
fun onClickCustomLogin(view: View){
    authListener?.onStarted()

    Coroutines.main {
        try {
            val authResult = repository.userLogin(email!!,password!!)
            authListener?.onSuccess()
        }catch (e : AuthExceptions){
           authListener?.onFailure(e.message!!)
        }
    }
}

我的 authListener 像这样

interface AuthListener {
  fun onStarted()
  fun onSuccess()
  fun onFailure(message: String)
}

由于任务未完成,我收到错误消息

是执行任务的正确方法

标签: androidandroid-studiokotlin-coroutines

解决方案


我正在使用 MVVM 架构模式,所以我要提供的示例是从我的ViewModel类中调用的,这意味着我可以访问viewModelScope. 如果要在Activity类上运行类似的代码,则必须使用可用于 Activity 的 Coroutines 范围,例如:

val uiScope = CoroutineScope(Dispatchers.Main)
uiScope.launch {...}

回答您的问题,我为从用户存储库检索登录所做的工作是:

//UserRepository.kt
class UserRepository(private val appAuth: FirebaseAuth) {

    suspend fun userLogin(email: String, password: String) : LoginResult{
        val firebaseUser = appAuth.signInWithEmailAndPassword(email, password).await()  // Do not forget .await()
        return LoginResult(firebaseUser)
    }
}

LoginResult 是 firebase 身份验证响应的包装类。

//ClassViewModel.kt
class LoginFirebaseViewModel(): ViewModel(){
    private val _loginResult = MutableLiveData<LoginResult>()
    val loginResult: LiveData<LoginResult> = _loginResult

    fun login() {
        viewModelScope.launch {
            try {
                repository.userLogin(email!!,password!!).let {
                    _loginResult.value = it
                }
            } catch (e: FirebaseAuthException) {
                // Do something on firebase exception
            }       
        }
    }
}

Activity 类的代码是这样的:

// Function inside Activity
fun onClickCustomLogin(view: View){

    val uiScope = CoroutineScope(Dispatchers.Main)
    uiScope.launch {
        try {
            repository.userLogin(email!!,password!!).let {
                authResult = it
            }
        }catch (e : FirebaseAuthException){
            // Do something on firebase exception
        }
    }
}

使用协程的主要好处之一是您可以按顺序转换异步代码。这意味着您不需要侦听器或回调。

我希望这对你有帮助


推荐阅读