我有一个简单的应用程序,它包含一个TextView并将数据存储在房间数据库中当数据库包含信息时,数据显示在文本视图中
问题当我从房间数据库中读取数据,并使用ViewModel在文本视图中首次显示数据库第一次为空时,应用程序崩溃!我已经用Recyclerview测试过了,回收视图是空的
问题为什么程序不显示空文本视图并崩溃,而Recycler视图中却不是这样?如何在文本视图中显示数据?
碎片中的我的代码
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
类MyViewModel(application:application(:AndroidViewModel(applications({
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()
}}
错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.student, PID: 2679
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.student.HomeFragment.onViewCreated$lambda-0(HomeFragment.kt:32)
at com.example.student.HomeFragment.$r8$lambda$kFVd0uSVK9JwnEU47m0mSdTzXmo(Unknown Source:0)
at com.example.student.HomeFragment$$ExternalSyntheticLambda0.onChanged(Unknown Source:4)
第32行为:txt_show_number.text=it[0]。question_number
您可能引用了不存在的元素,在这一行中:
txt_show_number.text=it[0]。question_number
尝试检查MutableLiveData对象中的列表是否为空,例如:
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"因为您没有使用视图模型协同程序调用数据库:(
ViewModel应该这样称呼它:
viewModelScope.launch(Dispatchers.IO) {...dbcall...}
(但不推荐-应该像文档所说的那样注入调度器(
这些操作是同步的,所以它们在协同程序中被调用以躲避ui阻塞。
另一个主题是使用索引,比如它[0],这是一个非常非常糟糕的习惯。
我认为有足够的信息如何开始房间,协同活动和视图模型,所以我不会垃圾邮件。