【问题标题】:How to solve "Cannot create an instance of class CoursesViewModel" error on Android Studio如何解决 Android Studio 上的“无法创建类 CoursesViewModel 的实例”错误
【发布时间】:2021-04-05 21:16:57
【问题描述】:

我是 Kotlin 的新手,我正在尝试使用依赖注入 (dagger.hilt) 创建一个 ViewModel 实例。我收到“无法创建类 CoursesViewModel 的实例”错误,我不知道为什么。你能帮我解决这个问题吗?

CoursesViewModel.kt

class CoursesViewModel @ViewModelInject constructor(
        private val courseDao: CourseDao
) : ViewModel() {
}

AppModule.kt

@Module
@InstallIn(ApplicationComponent::class)
object AppModule {

    @Provides
    @Singleton
    fun provideCourseDatabase(
            app: Application,
            callback: CourseDatabase.Callback
    ) = Room.databaseBuilder(app, CourseDatabase::class.java, "course_database")
            .fallbackToDestructiveMigration()
            .addCallback(callback)
            .build()

    @Provides
    fun provideCourseDao(db: CourseDatabase) = db.courseDao()

    @Provides
    @Singleton
    fun provideApplicationScope() = CoroutineScope(SupervisorJob())
}

CourseDatabase.kt

@Database(entities = [Course::class], version = 1)
abstract class CourseDatabase : RoomDatabase() {

    // DbSet equivalent
    abstract fun courseDao(): CourseDao

    // Inner callback class
    class Callback @Inject constructor(
            private val dbProvider: Provider<CourseDatabase>,
            @ApplicationScope
            private val applicationScope: CoroutineScope
    ) : RoomDatabase.Callback(){
        override fun onCreate(database: SupportSQLiteDatabase){
            super.onCreate(database)

            val courseDao = dbProvider.get().courseDao()

            applicationScope.launch {
                courseDao.insert(Course("my course")
            }
        }
    }
}

CoursesAllFragment.kt

class CoursesAllFragment : Fragment() {

    private val viewModel : CoursesViewModel by viewModels()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        val view: View = inflater.inflate(R.layout.fragment_courses_all, container, false)

        // Set the recycler view
        val recyclerView: RecyclerView = view.findViewById(R.id.lectures_classes_recycler_view)
        recyclerView.setHasFixedSize(true)
        recyclerView.setLayoutManager(LinearLayoutManager(context))
        recyclerView.setAdapter(CoursesAllAdapter(viewModel)) // Line 26. see: logcat
        return view
    }
}

logcat 输出:

2021-04-05 23:52:33.202 17137-17137/com.something.something E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.something.something, PID: 17137
    java.lang.RuntimeException: Cannot create an instance of class com.something.something.Courses.CoursesViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
        at com.something.something.Courses.Fragments.CoursesAllFragment.getViewModel(Unknown Source:2)
        //In the following line, "CoursesAllFragment.kt:26" is blue, which is where I pass the view model to an RecyclerViewAdapter.
        at com.something.something.Courses.Fragments.CoursesAllFragment.onCreateView(CoursesAllFragment.kt:26)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2950)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:277)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2177)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2088)
        at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1959)
        at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:306)
        at androidx.fragment.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:249)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
        at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
        at android.view.View.measure(View.java:25466)
        at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:792)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:583)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.layout(ConstraintWidgetContainer.java:682)
        at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solveLinearSystem(BasicMeasure.java:159)
        at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:290)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:119)
        at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1578)
        at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1690)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:25466)
        at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:792)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:583)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:355)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.solveVerticalMatchConstraint(Direct.java:636)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:407)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.solvingPass(Direct.java:178)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.layout(ConstraintWidgetContainer.java:642)
        at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solveLinearSystem(BasicMeasure.java:159)
2021-04-05 23:52:33.202 17137-17137/com.something.something E/AndroidRuntime:     at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:290)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:119)
        at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1578)
        at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1690)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:25466)
        at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:792)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:583)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:355)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.solveVerticalMatchConstraint(Direct.java:636)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:455)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:387)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.solvingPass(Direct.java:178)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.layout(ConstraintWidgetContainer.java:642)
        at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solveLinearSystem(BasicMeasure.java:159)
        at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:290)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:119)
        at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1578)
        at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1690)
        at android.view.View.measure(View.java:25466)
        at androidx.drawerlayout.widget.DrawerLayout.onMeasure(DrawerLayout.java:1156)
        at android.view.View.measure(View.java:25466)
        at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:792)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:583)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:355)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.solveVerticalMatchConstraint(Direct.java:636)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:407)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:446)
        at androidx.constraintlayout.solver.widgets.analyzer.Direct.solvingPass(Direct.java:178)
        at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.layout(ConstraintWidgetContainer.java:642)
        at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solveLinearSystem(BasicMeasure.java:159)

由于问题正文中的代码过多,Stackoverflow 不允许我粘贴 logcat 输出的其余部分。

【问题讨论】:

  • CoursesAllFragment 缺少@AndroidEntryPoint,但无论如何您也应该将您的 Hilt 更新到最新版本,您的版本大约是 2.28-alpha 左右,当前是 2.33-beta。
  • @EpicPandaForce 你的建议解决了它。添加这个作为答案。

标签: android kotlin dagger


【解决方案1】:

您需要使用@AndroidEntryPoint 标记您的片段和包含它们的活动,以便让 Hilt 知道在那里注入。

此外,最新版本的 Hilt 已弃用 @ViewModelInject 注释,转而使用 @HiltViewModel 注释实际视图模型类,并在构造函数上使用标准 Dagger @Inject 注释。

【讨论】:

    猜你喜欢
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    相关资源
    最近更新 更多