【问题标题】:Can't create VM with database in fragment (Kotlin)无法使用片段中的数据库创建 VM(Kotlin)
【发布时间】: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


    【解决方案1】:

    好的,所以我想通了,我只是缺少一些依赖项 kapt "androidx.room:room-compiler:$room_version"'kotlin-kapt' 插件

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多