简体   繁体   English

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

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

I have a simple app that contains a TextView and stores data in a room database When the database contains information, the data is displayed in the text view我有一个简单的应用程序,其中包含 TextView 并将数据存储在房间数据库中当数据库包含信息时,数据显示在文本视图中

problem When I read the data from the room database and show the first time in the text view with the ViewModel that the database is empty for the first time, the application crashes, I have tested it with Recyclerview, well the recyclerview was empty问题当我从房间数据库中读取数据并在文本视图中第一次使用 ViewModel 显示数据库为空时,应用程序崩溃,我用 Recyclerview 测试过,recyclerview 是空的

Question Why does the program not show the empty text view and it crashes, but this is not the case in Recycler View?问题为什么程序不显示空文本视图并崩溃,但在 Recycler View 中不是这种情况? How can I show the data in the text view?如何在文本视图中显示数据?

my code in fragment我的代码片段

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


    }

   
}

} }

ViewModel视图模型

class MyViewModel(application: Application): AndroidViewModel(application) { 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()

} } } }

It is possible that you are referencing to element which does not exist, in this line:您可能在此行中引用了不存在的元素:

txt_show_number.text = it[0].question_number txt_show_number.text = it[0].question_number

Try to check if list in MutableLiveData object is not empty, for example:尝试检查 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
    }

}

By the way - resolving your problem would be much easier, if you would attach crash error message from logcat, please kindly attach it next time.顺便说一句 - 解决您的问题会容易得多,如果您要附加来自 logcat 的崩溃错误消息,请下次附上。

I suspect the error goes like: "Cannot access database on the main thread since it may potentially lock the UI for a long periods of time."我怀疑错误类似于:“无法访问主线程上的数据库,因为它可能会长时间锁定 UI。” because you are not calling database with view model coroutines:)因为您没有使用视图 model 协程调用数据库:)

ViewModel is supposed to call it like: ViewModel 应该这样称呼它:

viewModelScope.launch(Dispatchers.IO) {...dbcall...} (not recommended though - dispatchers should be injected as docs say) viewModelScope.launch(Dispatchers.IO) {...dbcall...} (虽然不推荐 - 应该像文档所说的那样注入调度程序)

These operations are synced, so they are called in coroutine to dodge ui blocking.这些操作是同步的,所以在协程中调用它们来躲避 ui 阻塞。

Another topic is that you're using indexes, like it[0] which is very very bad habbit.另一个主题是您正在使用索引,例如 it[0],这是非常非常糟糕的习惯。

I think there is sufficient information how to start with ROOM, coroutines and viewmodels so I won't spam.我认为有足够的信息如何从 ROOM、协程和视图模型开始,所以我不会垃圾邮件。

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

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