gpt4 book ai didi

android - 改造协程 livedata 仅第一次调用

转载 作者:行者123 更新时间:2023-12-02 12:07:09 25 4
gpt4 key购买 nike

我刚接触 kotlin 协程。我刚刚创建了用于测试 livedata 的新项目,但我无法观察到数据的变化。我不明白livedata的概念。什么时候触发?因为当我观察 ROOM 数据库(不是协程方式。我使用 MutableLiveData)时,它工作得很好。每当数据发生变化时,总是会触发观察者。

我只是想清洁和现代的代码。我的期望:当我单击 btnLogin 按钮时(当用户使用另一个帐户登录或者您可以说数据更改时)livedata 必须触发。

这是我的例子:

改造界面:

interface RetroMainClient {

@POST("login.php")
suspend fun login(@Body model: UserLoginModel): Response<UserLoginModel>

companion object {
val getApi: RetroMainClient by lazy {
Retrofit.Builder().baseUrl("https://example.com/")
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().create())).build()
.create(RetroMainClient::class.java)
}
}
}

我的存储库:
class Repository {
suspend fun getLoginApi(model: UserLoginModel) = RetroMainClient.getApi.login(model)
}

我的 View 模型:
class MainViewModel : ViewModel() {

fun login(model: UserLoginModel) = liveData(IO) {
try {
emit(Repository().getLoginApi(model))
} catch (e: Exception) {
Log.e("exception", "${e.message}")
}
}
}

和我的 MainActivity:
class MainActivity : AppCompatActivity() {

private lateinit var viewModel: MainViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

var model = UserLoginModel("user1", "123456")

viewModel.login(model).observe(this, Observer {

if (it.isSuccessful) {
btnLogin.text = it.body()?.username
}

})

btnLogin.setOnClickListener {
model = UserLoginModel("user2", "123456")

CoroutineScope(IO).launch {
try {
Repository().getLoginApi(model)
} catch (e: Exception) {
Log.e("exception:", "${e.message}")
}
}
}
}
}

最佳答案

当您调用 viewModel.login() 方法时,您会创建 LiveData 类的新实例。为了在每次单击 viewModel.login() 按钮后执行 btnLogin 中的相应 block ,您需要为每个 LiveData.observe() 调用调用 viewModel.login() 方法。
MainActivityonCreate 方法中:

btnLogin.setOnClickListener {
model = UserLoginModel("user2", "123456")
viewModel.login(model).observe(this, Observer { data ->
if (it.isSuccessful) {
btnLogin.text = data.body()?.username
}
})
}
另一种方法 :
是在 MainViewModel 类中启动 协程 并手动更新 LiveData 字段:
class MainViewModel : ViewModel() {

val loginResponse: LiveData<Response<UserLoginModel>> = MutableLiveData<Response<UserLoginModel>>()

fun login(model: UserLoginModel) = viewModelScope.launch(IO) {
try {
(loginResponse as MutableLiveData).postValue(Repository().getLoginApi(model))
} catch (e: Exception) {
Log.e("exception", "${e.message}")
}
}
}


class MainActivity : AppCompatActivity() {

private lateinit var viewModel: MainViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

var model = UserLoginModel("user1", "123456")

viewModel.loginResponse.observe(this, Observer {

if (it.isSuccessful) {
btnLogin.text = it.body()?.username
}

})

btnLogin.setOnClickListener {
model = UserLoginModel("user2", "123456")

viewModel.login(model)
}
}
}
要在 viewModelScope 类中使用 MainViewModel,请将依赖项添加到 build.gradle 文件:

final LIFECYCLE_VERSION = "2.2.0-rc03" // add most recent version

api "androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VERSION"

关于android - 改造协程 livedata 仅第一次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59234698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com