android - 我从不进入我的 ViewModel 中的 LiveDataScope

标签 android kotlin viewmodel android-livedata kotlin-coroutines

我开发了 2 个登录功能。

第一个“loginOne”在我使用 ViewModel 范围时有效。

当我使用 LiveData 范围时,另一个不起作用。

你有想法吗?我想让“loginTwo”工作。

API

interface LoginAPI {

    @POST("login")
    suspend fun getUser(@Body loginRequest: LoginRequest): User
}

存储库

class LoginRepository(private val loginAPI: LoginAPI) {

    suspend fun getUser(loginRequest: LoginRequest) = loginAPI.getUser(loginRequest)
}

View 模型

class LoginViewModel(private val loginRepository: LoginRepository) : ViewModel() {

    private var user: LiveData<User>? = null

    fun loginOne(username: String, password: String) {
        viewModelScope.launch {
            // i can enter here and get the user :)
            val user = loginRepository.getUser(LoginRequest(username, password))
            user
        }
    }

    fun loginTwo(username: String, password: String) {
        user = liveData(Dispatchers.IO) {
            // i never enter inside.. why ?
            val user = loginRepository.getUser(LoginRequest(username, password))
            emit(user)
        }
    }

    fun getUser(): LiveData<User>? = user
}

fragment ,我的viewModel注入(inject)了Koin

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
   super.onViewCreated(view, savedInstanceState)

   loginViewModel.getUser()?.observe(this, Observer { user ->
       Log.d(LoginFragment::class.java.name, "User : $user ")
   })

   loginViewModel.loginOne("user","pcw123")
   loginViewModel.loginTwo("user","pcw123")
}

最佳答案

确保您以正确的方式创建了Scope。此外,您正在使用适当的 Dispatchers 来实现所需的结果。

您还可以检查调用是否在您想要 postValue 时执行。 检查 Job 是否仍然存在。

检查这个thing . 您的 emmit 调用看起来很可疑。

When using LiveData, you might need to calculate values asynchronously. For example, you might want to retrieve a user's preferences and serve them to your UI. In these cases, you can use the liveData builder function to call a suspend function, serving the result as a LiveData object.

Each emit() call suspends the execution of the block until the LiveData value is set on the main thread.

In the example below, loadUser() is a suspend function declared elsewhere. Use the liveData builder function to call loadUser() asynchronously, and then use emit() to emit the result:

val user: LiveData<User> = liveData {
    val data = database.loadUser() // loadUser is a suspend function.
    emit(data)
}

编辑 MutableLiveData for user 变量 - 解决了问题。

关于android - 我从不进入我的 ViewModel 中的 LiveDataScope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59990612/

相关文章:

android - 更改 TextInputLayout 提示字体

MVVM:删除一个 CustomerViewModel,但如何获取其中的 Customer 模型?

wpf - 类项目中的 ViewModel

android - 从使用 Widget.EditText 样式的 TextView 中删除下划线

android - 操作栏中的 AutoCompleteTextView 不起作用?

java - Android 软键盘在重新打开时隐藏 EditText

asp.net-mvc - 带有 SelectList 设计决策的 ViewModels

android - Kotlin object/singleton 的方法是否同步?

android - 为什么对象必须在传递给 android 中的 Activity 之前进行序列化?

arrays - 如何在Kotlin中将对象, bool 值和long值添加到数组中?