如何获取LivaData< String>的值?一次在Android Studio中? [英] How can I get the value of a LivaData<String> at once in Android Studio?

查看:81
本文介绍了如何获取LivaData< String>的值?一次在Android Studio中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

savedRecordFileName LivaData< String> 的变量,我希望立即在代码A中获取 savedRecordFileName 的值.

您知道LiveData变量是惰性的,也许 savedRecordFileName 的值在 binding.btnStop.setOnClickListener {} 中为空,所以在 binding中的代码.当 savedRecordFileName 的值为空时,不会触发btnStop.setOnClickListener {} .

我希望 binding.btnStop.setOnClickListener {} 中的代码始终可以被触发,我该怎么办?

顺便说一句,我认为代码B不适合,因为 savedRecordFileName 的值可能会被其他函数更改.

代码B

  binding.btnStop.setOnClickListener {mHomeViewModel.savedRecordFileName.observe(viewLifecycleOwner){val aMVoice = getDefaultMVoice(mContext,it)mHomeViewModel.add(aMVoice)}} 

代码A

  class FragmentHome:Fragment(){私人val mHomeViewModel,由lazy {getViewModel {HomeViewModel(mActivity.application,ProvideRepository(mContext))}}重写fun onCreateView(inflater:LayoutInflater,container:ViewGroup ?, savedInstanceState:Bundle?):视图?{...binding.btnStop.setOnClickListener {mHomeViewModel.savedRecordFileName.value?.let {val aMVoice = getDefaultMVoice(mContext,it)mHomeViewModel.add(aMVoice)}}...返回binding.root}}class HomeViewModel(val mApplication:Application,私有val mDBVoiceRepository:DBVoiceRepository):AndroidViewModel(mApplication){val savedRecordFileName:LiveData< String>= mDBVoiceRepository.getTotalOfVoice().map {mApplication.getString(R.string.defaultName,(it + 1).toString())}}类DBVoiceRepository私有构造函数(private val mDBVoiceDao:DBVoiceDao){有趣的getTotalOfVoice()= mDBVoiceDao.getTotalOfVoice()}@道介面DBVoiceDao {@Query(来自voice_table的SELECT count(id)")fun getTotalOfVoice():LiveData< Long>} 

添加内容

致Ridcully:谢谢!

我认为您的方式将所有这些都移到了viewmodel类中"很好!

即使您的代码C中的 filename 是livedata,我认为也可以,对吧?

代码C

  viewModelScope.launch(Dispatchers.IO){filename = dao.getFilename()//不包含livedata.我认为即使文件名是livedata也可以voice = getDefaultVoice(...)//也可以在后台执行此操作加(语音)result.postValue(true)} 

正如您所说,

解决方案

您应该在后台执行Room查询,以避免阻塞ui线程.但是你不应该就此止步.在后台线程中做尽可能多的工作.在您的情况下,单击按钮后,开始运行一个后台线程来完成所有工作:从数据库获取名称(通过直接查询,现在可以在后台运行,现在可以),获取默认声音并将其添加到不管您要添加到什么.

您还应该将所有这些都移到viewmodel类中.

  btnStop.setOnClickListener {viewmodel.stop()} 

在viewmodel中,像这样的东西(类似Java/伪代码):

  void stop(){runinbackgroundthread {filename = dao.getFilename()//不包含livedatavoice = getDefaultVoice(...)//也可以在后台执行此操作加(语音)//如果您希望该操作引起误解,则可通过ui进行观察//使用MutableLiveData并通过postValue()在此处进行设置//,因为我们仍在后台线程中.result.postValue(true)}} 

有关如何实际实现我的伪代码 runinbackgroundthread 的信息,请参见此处的一些官方指南: 解决方案

As you said, you should do Room queries in background to avoid blocking ui thread. But you shouldn't stop there. Do as much work as possible in a background thread. In your case, on button click, start running a background thread that does all the work: getting name from database (with direct query, which is possible now as you are running in background), getting the default voice, and adding it, to whatever it is you are adding it to.

You should also move all of that into the viewmodel class.

btnStop.setOnClickListener {
    viewmodel.stop()
}

In viewmodel something like this (java / pseudo code like):

void stop() {
    runinbackgroundthread {
        filename = dao.getFilename() // without livedata
        voice = getDefaultVoice(...) // also do this in background
        add(voice)
        // If you want the action to have a reault, observable by ui
        // use a MutableLiveData and set it here, via postValue()
        // as we are still in background thread.
        result.postValue(true)
    }
}

On how to actually implement my pseudo code runinbackgroundthread see some official guide here: https://developer.android.com/guide/background/threading

In short, with Kotlin coroutines it should go like this:

viewModelScope.launch(Dispatchers.IO) {
    filename = dao.getFilename() // without livedata
    voice = getDefaultVoice(...) // also do this in background
    add(voice)
    result.postValue(true)
}

这篇关于如何获取LivaData&lt; String&gt;的值?一次在Android Studio中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆