我试图理解这最后一步。

我需要执行一次原子操作,我需要转到Firebase并放置我的用户设备 token 。

为此,我只是在viewModel中调用一个会触发我的仓库的方法,但是现在,我不想在仓库中使用LiveData,相反,我只是想从那里返回Resource,但是由于这是一个异步方法,不能再回来。

我只想在ViewModel上使用LiveData,而不要在存储库中使用LiveData,该存储库应仅将对象传递给我的viewModel,而viewModel应将这些对象传递给我的 View 。

View

viewModel.userToken.observe(this, Observer {
            when (it.status) {
                Status.SUCCESS -> {
                    val user = FirebaseAuth.getInstance().currentUser
                    startActivity(Intent(this, SecondActivity::class.java))
                    Toast.makeText(this, "Welcome ${user!!.uid} !", Toast.LENGTH_SHORT).show()
                    finish()
                }

                Status.ERROR -> {
                }

                else -> {
                    Toast.makeText(this, "error ${it.message}", Toast.LENGTH_SHORT).show()
                }
            }
        })

View 模型
class LoginViewModel: ViewModel() {

    private val useCase = PostUserToken(UserRepo())
    var userToken = liveData(Dispatchers.IO){
        emit(useCase.postUserToken())
    }

}

直到这里工作正常,直到从仓库中的postUserToken()方法开始,我需要将Resource<Boolean>对象返回到我的viewmodel中,如何使用协同程序来做到这一点?

用例
class PostUserToken(private val repo: UserRepo) {

    suspend fun postUserToken(): Resource<Boolean> = repo.saveUserToken()

}

回购
class UserRepo {

    suspend fun saveUserToken(): Resource<Boolean> {
        FirebaseInstanceId.getInstance().instanceId
            .addOnCompleteListener(OnCompleteListener { task ->
                if (!task.isSuccessful) {
                    Log.w("saveUserToken", "getInstanceId failed", task.exception)
                    return@OnCompleteListener
                }

                // Get new Instance ID token
                val token = task.result?.token

            })

        //Here I need to return the Resource<Boolean> but wait untill it completes
    }
}

这是我使用的两个帮助程序类

资源资源
data class Resource<out T>(val status: Status, val data: T?, val message: String?) {

    companion object {
        fun <T> success(data: T?): Resource<T> {
            return Resource(Status.SUCCESS, data, null)
        }

        fun <T> error(msg: String, data: T?): Resource<T> {
            return Resource(Status.ERROR, data, msg)
        }

        fun <T> loading(data: T?): Resource<T> {
            return Resource(Status.LOADING, data, null)
        }
    }
}

状态
enum class Status {
    SUCCESS,
    ERROR,
    LOADING
}

当需要将对象交付给其他类时,我总是被困在存储库中,这是交付此流程的最佳方法?

我知道如果我需要继续收听,应该将Flow与Coroutines一起使用,但是现在我只需要一次操作就可以在所有类中传递该对象到我的 View 中

谢谢

最佳答案

存储库对象返回LiveData完全有效。那就是我会做的。我不认为您应该尝试使其同步返回任何内容,因为这完全违反了协程的目的。

如果要使用带有协程的Task,请研究使用此库,该库将播放服务Task对象转换为可以在暂挂乐趣中等待的对象:

https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-play-services

07-26 08:49
查看更多