Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 仅第一次调用Retroift协同路由livedata_Android_Kotlin_Android Livedata_Android Architecture Components_Kotlin Coroutines - Fatal编程技术网

Android 仅第一次调用Retroift协同路由livedata

Android 仅第一次调用Retroift协同路由livedata,android,kotlin,android-livedata,android-architecture-components,kotlin-coroutines,Android,Kotlin,Android Livedata,Android Architecture Components,Kotlin Coroutines,我刚加入科特林公司。我刚刚创建了一个新项目来测试livedata,但我无法观察数据的变化。我不理解livedata的概念。什么时候触发?因为当我观察ROOM数据库时(不是以协同程序的方式,我使用了MutableLiveData),它工作得非常好。每次数据更改时,都会触发Observer 我只是想要干净和现代的代码。我的期望:当我点击btnLogin按钮时(当用户使用另一个帐户登录时,或者您可以说当数据更改时),必须触发livedata 以下是我的例子: 改装接口: interface Retro

我刚加入科特林公司。我刚刚创建了一个新项目来测试livedata,但我无法观察数据的变化。我不理解livedata的概念。什么时候触发?因为当我观察ROOM数据库时(不是以协同程序的方式,我使用了MutableLiveData),它工作得非常好。每次数据更改时,都会触发Observer

我只是想要干净和现代的代码。我的期望:当我点击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)
        }
    }
}
我的viewModel:

class MainViewModel : ViewModel() {

    fun login(model: UserLoginModel) = liveData(IO) {
        try {
            emit(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.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
按钮后,您需要调用
LiveData.observe()
方法来调用每个
viewModel.login()

MainActivity
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)
        }
    }
}
class MainViewModel:ViewModel(){
val loginResponse:LiveData=MutableLiveData()
有趣的登录(模型:UserLoginModel)=viewModelScope.launch(IO){
试一试{
(loginResponse为MutableLiveData).postValue(Repository().getLoginApi(model))
}捕获(e:例外){
Log.e(“异常”,“${e.message}”)
}
}
}
类MainActivity:AppCompatActivity(){
私有lateinit变量viewModel:MainViewModel
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel=ViewModelProvider(this.get)(MainViewModel::class.java)
var模型=UserLoginModel(“user1”、“123456”)
viewModel.loginResponse.observe(此,观察者{
如果(it.ISSUCCESS){
btnLogin.text=it.body()?.username
}
})
btnLogin.setOnClickListener{
模型=用户登录模型(“用户2”、“123456”)
viewModel.login(模型)
}
}
}
要在
MainViewModel
类中使用
viewModelScope
,请将依赖项添加到build.gradle文件:

最终生命周期\u VERSION=“2.2.0-rc03”//添加最新版本

api“androidx.lifecycle:lifecycle viewmodel ktx:$lifecycle\u版本”


我不知道该怎么感谢你。我研究了几个小时,我知道每次单击按钮都会创建新实例。但我不知道如何避免它。非常感谢。你救了我的命:)
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)
        }
    }
}