如何解决 Android Studio 上的 "Cannot create an instance of class CoursesViewModel" 错误
How to solve "Cannot create an instance of class CoursesViewModel" error on Android Studio
我是 Kotlin 的新手,我正在尝试使用依赖注入 (dagger.hilt) 创建一个 ViewModel 实例。我收到“无法创建 class 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)
由于问题正文中的代码过多,Whosebug 不允许我粘贴 logcat 输出的其余部分。
您需要用 @AndroidEntryPoint
标记您的片段和包含它们的活动,让 Hilt 知道要在那里注入。
此外,最新版本的 Hilt 已弃用 @ViewModelInject
注释,转而使用 @HiltViewModel
注释实际视图模型 class 并使用标准 Dagger @Inject
注释在构造函数上。
我是 Kotlin 的新手,我正在尝试使用依赖注入 (dagger.hilt) 创建一个 ViewModel 实例。我收到“无法创建 class 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)
由于问题正文中的代码过多,Whosebug 不允许我粘贴 logcat 输出的其余部分。
您需要用 @AndroidEntryPoint
标记您的片段和包含它们的活动,让 Hilt 知道要在那里注入。
此外,最新版本的 Hilt 已弃用 @ViewModelInject
注释,转而使用 @HiltViewModel
注释实际视图模型 class 并使用标准 Dagger @Inject
注释在构造函数上。