【发布时间】:2021-11-05 10:35:05
【问题描述】:
所以我在片段类中创建 ViewModel 时遇到问题。我正在关注本教程: https://developer.android.com/codelabs/android-room-with-a-view-kotlin 当我切换到要填充的 RecycleView 片段时,我的应用程序崩溃了。由于某种原因,当我附加观察者时,我从堆栈跟踪中收集到我的数据库 impl 不存在。在这一点上,我有点迷路了,应该
- 堆栈跟踪
java.lang.RuntimeException: cannot find implementation for com.example.calorycalckotlinedition.data.CaloryDB. CaloryDB_Impl does not exist
at androidx.room.Room.getGeneratedImplementation(Room.java:94)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:667)
at com.example.calorycalckotlinedition.data.CaloryDB$Companion.getDatabase(CaloryDB.kt:62)
at com.example.calorycalckotlinedition.DataBaseApp$database$2.invoke(DataBaseApp.kt:13)
at com.example.calorycalckotlinedition.DataBaseApp$database$2.invoke(DataBaseApp.kt:13)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.example.calorycalckotlinedition.DataBaseApp.getDatabase(DataBaseApp.kt:13)
at com.example.calorycalckotlinedition.DataBaseApp$repository$2.invoke(DataBaseApp.kt:14)
at com.example.calorycalckotlinedition.DataBaseApp$repository$2.invoke(DataBaseApp.kt:14)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.example.calorycalckotlinedition.DataBaseApp.getRepository(DataBaseApp.kt:14)
at com.example.calorycalckotlinedition.appUI.HistoryFragment$onViewCreated$historyVM$2.invoke(HistoryFragment.kt:50)
at com.example.calorycalckotlinedition.appUI.HistoryFragment$onViewCreated$historyVM$2.invoke(HistoryFragment.kt:49)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:52)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at com.example.calorycalckotlinedition.appUI.HistoryFragment.onViewCreated$lambda-0(HistoryFragment.kt:49)
at com.example.calorycalckotlinedition.appUI.HistoryFragment.onViewCreated(HistoryFragment.kt:53)
...
- MyDB
@Database(entities = [History::class,Product::class], version = 1, exportSchema = false)
abstract class CaloryDB : RoomDatabase() {
abstract fun HistoryDao(): HistoryDao
private class WordDatabaseCallback(private val scope: CoroutineScope) : RoomDatabase.Callback(){
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
INSTANCE?.let { database -> scope.launch {
val historyDao = database.HistoryDao()
// Delete all content here.
historyDao.deleteAll()
val date1 : Date = GregorianCalendar(2021, 11, 1).time
val date2 : Date = GregorianCalendar(2021, 11, 2).time
val date3 : Date = GregorianCalendar(2021, 11, 3).time
val date4 : Date = GregorianCalendar(2021, 11, 4).time
val history1 = History(date1,-1.0f,0.0f,0.0f,0.0f,0.0f,0.0f)
val history2 = History(date2,-1.0f,0.0f,0.0f,0.0f,0.0f,0.0f)
val history3 = History(date3,-1.0f,0.0f,0.0f,0.0f,0.0f,0.0f)
val history4 = History(date4,-1.0f,0.0f,0.0f,0.0f,0.0f,0.0f)
historyDao.insert(history1)
historyDao.insert(history2)
historyDao.insert(history3)
historyDao.insert(history4)
}
}
}
}
companion object {
@Volatile
private var INSTANCE: CaloryDB? = null
fun getDatabase(
context: Context,
scope: CoroutineScope
): CaloryDB {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
CaloryDB::class.java,
"word_database"
)
.addCallback(WordDatabaseCallback(scope))
.build()
INSTANCE = instance
// return instance
instance
}
}
}
}
- 数据库应用程序
class DataBaseApp : Application(){
val applicationScope = CoroutineScope(SupervisorJob())
val database by lazy { CaloryDB.getDatabase(this,applicationScope)}
val repository by lazy { HistoryRepo(database.HistoryDao()) }
}
- 片段
class HistoryFragment : Fragment(R.layout.fragment_history) {
lateinit var adapter: HistoryListAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d(TAG,"inflate")
val view = inflater.inflate(R.layout.fragment_history, container, false)
Log.d(TAG,"Set up adapter")
val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerViewHistory)
adapter = HistoryListAdapter()
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(view.context)
return view;
}
override fun onViewCreated(view: android.view.View, savedInstanceState: android.os.Bundle?) {
super.onViewCreated(view, savedInstanceState)
val historyVM: HistoryVM by activityViewModels {
HistoryVMFactory((requireActivity().application as DataBaseApp).repository)
}
historyVM.allRecords.observe(viewLifecycleOwner, Observer { records ->
records?.let { adapter.submitList(it) }
})
}
}
【问题讨论】:
标签: kotlin android-room android-viewmodel