绑定到 android 中的挂起函数

H.s*_*ati 3 android kotlin android-databinding kotlin-coroutines

我想将按钮单击绑定到视图模型内的挂起函数。

这是我的代码:

RegistrationActivityViewModel.kt

    suspend fun register() {
        if (validateFields()) {
            val result = SourceplusplusApiService.invoke().registerUser(username.value!!, email.value!!, password.value!!).await()
            isRegistrationCompleted.value = getResultValue(result)
        }
    }
Run Code Online (Sandbox Code Playgroud)

活动注册.xml

<Button
          android:text="Register"
          android:onClick="@{()->viewmodel.register()}"
          android:textSize="16sp" />
Run Code Online (Sandbox Code Playgroud)

我收到一个数据绑定错误,提示ActivityRegistrationBindingImpl未生成。经过大量搜索后,我意识到当我删除suspend关键字并注释里面的代码时,它工作正常,但它必须是一个挂起的函数。

有谁知道如何修理它?

Com*_*are 7

您无法将数据绑定到suspend函数,并且恕我直言,视图模型不应该suspend首先公开函数。我建议:

步骤#1:删除suspend关键字register()

步骤#2:重写register()以在合适的协程作用域中运行代码,以便suspend正确处理它调用的任何函数:

fun register() {
    viewModelScope.launch(Dispatchers.Main) {
        if (validateFields()) {
            val result = SourceplusplusApiService.invoke().registerUser(username.value!!, email.value!!, password.value!!).await()
            isRegistrationCompleted.value = getResultValue(result)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我使用的是版本及更新版本viewModelScope提供的选项。或者,管理您自己的协程范围。将确保您可以在 Android 主应用程序线程上使用该工作的任何结果。androidx.lifecycle:lifecycle-viewmodel-ktx2.1.0-alpha01Dispatchers.Main

现在,您的数据绑定表达式可以引用register(),同时您仍然具有用于调用下游函数的协程作用域suspend

  • @MarkoTopolnik:可能,但我更喜欢在像这样的教育材料中拼写出来。 (4认同)
  • “Main”不是已经是“viewModelScope”的默认调度程序了吗? (2认同)