回溯协程仅实时调用实时数据

时间:2019-12-08 10:58:45

标签: android kotlin android-livedata android-architecture-components kotlin-coroutines

我刚接触Kotlin协程。我刚刚创建了一个用于测试实时数据的新项目,但无法观察数据变化。我不了解实时数据的概念。什么时候会触发?因为当我观察ROOM数据库(不是协程方式。我使用MutableLiveData)时,它运行得很好。每当数据更改时,都会触发观察者。

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

这是我的示例:

改造界面:

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)
}

我的viewModel:

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}")
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

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

MainActivity的{​​{1}}方法中:

onCreate

另一种方法

是要在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,请向build.gradle文件添加依赖项:

  

final LIFECYCLE_VERSION =“ 2.2.0-rc03” //添加最新版本

     

api“ androidx.lifecycle:lifecycle-viewmodel-ktx:$ LIFECYCLE_VERSION”