You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建ViewModel时出现Cannot create an instance of class错误求助

问题:Cannot create an instance of class ViewModel错误

创建ViewModel时触发Cannot create an instance of class错误,应用在ViewModel初始化阶段崩溃,多次重构相关类仍未解决。

相关代码

Activity类

@AndroidEntryPoint
class FamiliarActivity : AppCompatActivity() {

    private val noticeScreenViewModel : NoticeScreenViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            FamiliarTheme {
                val navController = rememberNavController()
                val currentBackStack by navController.currentBackStackEntryAsState()
                val currentDestination = currentBackStack?.destination
                val currentScreen =
                    familiarScreens.find { it.route == currentDestination?.route } ?: Settings

                FamiliarNavHost(
                    noticesViewModel = noticeScreenViewModel,
                    navController = navController,
                    modifier = Modifier.padding()
                )
            }
        }
    }
}

NoticeScreenViewModel类

@HiltViewModel
class NoticeScreenViewModel @Inject internal constructor(
    private val noticeRepository: NoticeRepository
) : ViewModel(){
    val notices: List<Notice> = noticeRepository.getNotices()

}

NoticeRepository类

class NoticeRepository @Inject constructor(
    private val noticeDao: NoticeDao
) {

        fun createNotice(notice: Notice) {
            noticeDao.insert(notice)
        }

        fun removeNotice(notice: Notice) {
            noticeDao.delete(notice)
        }

        fun getNotices() = noticeDao.getNotices()

        companion object {

            // For Singleton instantiation
            @Volatile private var instance: NoticeRepository? = null

            fun getInstance(noticeDao: NoticeDao) =
                instance ?: synchronized(this) {
                    instance ?: NoticeRepository(noticeDao).also { instance = it }
                }
        }
}

NoticeDao接口

@Dao
interface NoticeDao {
    @Query("SELECT * FROM notice")
    fun getNotices(): List<Notice>

    @Insert
    fun insertAll(vararg notices: Notice)

    @Insert
    fun insert(notice: Notice)

    @Delete
    fun delete(notice: Notice)

}

崩溃堆栈信息

FATAL EXCEPTION: main
Process: com.dmlpcb.familiar, PID: 27627
java.lang.RuntimeException: Cannot create an instance of class com.dmlpcb.familiar.ui.NoticeScreenViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:204)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:324)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:306)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:280)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.kt:128)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:153)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:53)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:35)
at com.dmlpcb.familiar.FamiliarActivity$noticeScreenViewModel$2.invoke(FamiliarActivity.kt:23)
at com.dmlpcb.familiar.FamiliarActivity$noticeScreenViewModel$2.invoke(FamiliarActivity.kt:22)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.dmlpcb.familiar.FamiliarActivity.getNoticeScreenViewModel(FamiliarActivity.kt:22)
at com.dmlpcb.familiar.FamiliarActivity.access$getNoticeScreenViewModel(FamiliarActivity.kt:19)
at com.dmlpcb.familiar.FamiliarActivity$onCreate$1$1.invoke(FamiliarActivity.kt:36)
at com.dmlpcb.familiar.FamiliarActivity$onCreate$1$1.invoke(FamiliarActivity.kt:28)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.TextKt.ProvideTextStyle(Text.kt:360)
at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:81)
at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:80)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:73)
at com.dmlpcb.familiar.compose.ThemesKt.FamiliarTheme(Themes.kt:22)
at com.dmlpcb.familiar.FamiliarActivity$onCreate$1.invoke(FamiliarActivity.kt:28)
at com.dmlpcb.familiar.FamiliarActivity$onCreate$1.invoke(FamiliarActivity.kt:27)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:428)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:252)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:251)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:195)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:119)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:118)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:110)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:158)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:157)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:157)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:142)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3340)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3273)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:588)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1013)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:142)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:133)
at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1191)
at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:133)
at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:183)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.kt:192)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:133)
at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:1266)
at android.view.View.dispatchAttachedToWindow(View.java:21980)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3490)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3014)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9305)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1339)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:882)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.NoSuchMethodException: com.dmlpcb.familiar.ui.NoticeScreenViewModel. []
at java.lang.Class.getConstructor0(Class.java:3325)
at java.lang.Class.getDeclaredConstructor(Class.java:3063)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:202)
... 92 more

解决方案

从崩溃栈的Caused by: java.lang.NoSuchMethodException: ... []可知,系统尝试寻找ViewModel的无参构造函数,但当前ViewModel使用Hilt依赖注入,问题核心是Hilt未正确接管ViewModel的创建流程,按以下步骤排查修复:

  1. 确认Hilt依赖配置完整

    • 项目级build.gradle需添加Hilt插件:
      plugins {
          id 'com.android.application' version 'xxx' apply false
          id 'org.jetbrains.kotlin.android' version 'xxx' apply false
          id 'com.google.dagger.hilt.android' version 'xxx' apply false
      }
      
    • 模块级build.gradle需启用Hilt插件并添加依赖:
      plugins {
          id 'com.android.application'
          id 'org.jetbrains.kotlin.android'
          id 'com.google.dagger.hilt.android'
      }
      
      dependencies {
          implementation "com.google.dagger:hilt-android:xxx"
          kapt "com.google.dagger:hilt-compiler:xxx"
          implementation "androidx.hilt:hilt-lifecycle-viewmodel:xxx"
          kapt "androidx.hilt:hilt-compiler:xxx"
      }
      
  2. 检查Application类的Hilt注解
    Hilt需要通过标记@HiltAndroidApp的Application类初始化依赖容器,确保存在该类:

    @HiltAndroidApp
    class MyApplication : Application() {
        // 空实现或自定义逻辑
    }
    

    同时在AndroidManifest.xml中指定该Application:

    <application
        android:name=".MyApplication"
        <!-- 其他配置项 -->
        >
    </application>
    
  3. 修正ViewModel的初始化方式
    对于Hilt注入的ViewModel,需使用Hilt提供的扩展函数获取:

    • 若在Compose NavHost中使用,直接在目标页面调用hiltViewModel():
      @Composable
      fun FamiliarNavHost(navController: NavHostController, modifier: Modifier = Modifier) {
          NavHost(navController = navController, startDestination = "xxx") {
              composable("xxx") {
                  val viewModel: NoticeScreenViewModel = hiltViewModel()
                  // 使用viewModel构建UI
              }
          }
      }
      
    • 若需在Activity中获取,确保导入Hilt的viewModels()扩展:
      import androidx.hilt.lifecycle.viewModels
      // 初始化代码保持不变,但需确保导入正确
      private val noticeScreenViewModel : NoticeScreenViewModel by viewModels()
      
  4. 调整Repository与Dao的注入逻辑

    • 移除NoticeRepository中的单例companion object,Hilt会自动管理实例生命周期,手动单例会与Hilt注入逻辑冲突,仅保留@Inject constructor即可。
    • 确保Room数据库类被Hilt正确提供:
      @Database(entities = [Notice::class], version = 1)
      abstract class AppDatabase : RoomDatabase() {
          abstract fun noticeDao(): NoticeDao
      }
      
      @Module
      @InstallIn(SingletonComponent::class)
      object DatabaseModule {
          @Provides
          @Singleton
          fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase {
              return Room.databaseBuilder(
                  context,
                  AppDatabase::class.java,
                  "app_database"
              ).build()
          }
      
          @Provides
          fun provideNoticeDao(appDatabase: AppDatabase): NoticeDao {
              return appDatabase.noticeDao()
          }
      }
      
  5. 清理缓存并重新构建项目
    编译缓存可能导致Hilt生成的代码异常,执行Build -> Clean Project和Build -> Rebuild Project,或删除项目根目录下的.gradle、build文件夹后重新编译。


内容的提问来源于stack exchange,提问作者Edmund Osborne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 10:34:50