我试图理解这最后一步。
我需要执行一次原子操作,我需要转到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