繁体   English   中英

当 viewmodel 在 TextView 中读取和设置数据时应用程序崩溃

[英]crash app when viewmodel read and set data in TextView

我有一个简单的应用程序,其中包含 TextView 并将数据存储在房间数据库中当数据库包含信息时,数据显示在文本视图中

问题当我从房间数据库中读取数据并在文本视图中第一次使用 ViewModel 显示数据库为空时,应用程序崩溃,我用 Recyclerview 测试过,recyclerview 是空的

问题为什么程序不显示空文本视图并崩溃,但在 Recycler View 中不是这种情况? 如何在文本视图中显示数据?

我的代码片段

class HomeFragment : Fragment() {


private lateinit var viewModel: MyViewModel
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_home, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewModel = ViewModelProvider(this)[MyViewModel::class.java]
    viewModel.getAllDataObservers().observe(viewLifecycleOwner){

        //textview for show data
        txt_show_number.text = it[0].question_number
        txt_show_question.text = it[0].question


    }

   
}

}

视图模型

class MyViewModel(应用程序:应用程序):AndroidViewModel(应用程序){

var allUsers: MutableLiveData<List<EntityStudent>> = MutableLiveData()


fun getAllDataObservers(): MutableLiveData<List<EntityStudent>> {
    getAllData()
    return allUsers

}

fun getAllData() {
    val dao = RoomDb.getAppDatabase((getApplication()))?.mainDao()
    val list = dao?.getAllData()
    allUsers.postValue(list!!)


}

fun insert(entityStudent: EntityStudent) {
    val dao = RoomDb.getAppDatabase((getApplication()))?.mainDao()
    val list = dao?.insert(entityStudent)
    getAllData()

} }

您可能在此行中引用了不存在的元素:

txt_show_number.text = it[0].question_number

尝试检查 MutableLiveData object 中的列表是否不为空,例如:

viewModel.getAllDataObservers().observe(viewLifecycleOwner){
   if(it.size > 0){
        //textview for show data
        txt_show_number.text = it[0].question_number
        txt_show_question.text = it[0].question
    }

}

顺便说一句 - 解决您的问题会容易得多,如果您要附加来自 logcat 的崩溃错误消息,请下次附上。

我怀疑错误类似于:“无法访问主线程上的数据库,因为它可能会长时间锁定 UI。” 因为您没有使用视图 model 协程调用数据库:)

ViewModel 应该这样称呼它:

viewModelScope.launch(Dispatchers.IO) {...dbcall...} (虽然不推荐 - 应该像文档所说的那样注入调度程序)

这些操作是同步的,所以在协程中调用它们来躲避 ui 阻塞。

另一个主题是您正在使用索引,例如 it[0],这是非常非常糟糕的习惯。

我认为有足够的信息如何从 ROOM、协程和视图模型开始,所以我不会垃圾邮件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM