简体   繁体   中英

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

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

Question Why does the program not show the empty text view and it crashes, but this is not the case in 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) {

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

Try to check if list in MutableLiveData object is not empty, for example:

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.

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." because you are not calling database with view model coroutines:)

ViewModel is supposed to call it like:

viewModelScope.launch(Dispatchers.IO) {...dbcall...} (not recommended though - dispatchers should be injected as docs say)

These operations are synced, so they are called in coroutine to dodge ui blocking.

Another topic is that you're using indexes, like it[0] which is very very bad habbit.

I think there is sufficient information how to start with ROOM, coroutines and viewmodels so I won't spam.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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