当前位置: 首页 > 知识库问答 >
问题:

为什么我在kotlin中的应用程序在调用协同程序时崩溃?

田晨
2023-03-14

我试图调用ViewModel中片段中的函数,但每次调用时它都会崩溃,我不知道为什么。下面是代码:

呼吁协程:

binding.button.setOnClickListener {
            lifecycleScope.launch(Dispatchers.IO){
                courseViewModel.repository.insertCourse(getData())
            }
            Navigation.findNavController(it).popBackStack()
        }

函数的代码:suspend fun insertCourse(课程:课程)=courseDAO。insertCourse(课程)

如果我不使用协同程序,只使用courseViewModel。存储库。insertCourse(getData())我收到一个错误,说我必须从其他挂起函数或协同程序调用这个函数。

这就是错误:

2022-03-20 13:33:43.893 28396-28437/com.example.cursosmvvm E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
    Process: com.example.cursosmvvm, PID: 28396
    java.lang.RuntimeException: Cannot create an instance of class domain.CourseViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:188)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:169)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:44)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:31)
        at ui.NewCourseFragment.getCourseViewModel(NewCourseFragment.kt:23)
        at ui.NewCourseFragment.access$getCourseViewModel(NewCourseFragment.kt:20)
        at ui.NewCourseFragment$onViewCreated$1$1.invokeSuspend(NewCourseFragment.kt:58)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
     Caused by: java.lang.InstantiationException: java.lang.Class<domain.CourseViewModel> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:186)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238) 
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:169) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139) 
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:44) 
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:31) 
        at ui.NewCourseFragment.getCourseViewModel(NewCourseFragment.kt:23) 
        at ui.NewCourseFragment.access$getCourseViewModel(NewCourseFragment.kt:20) 
        at ui.NewCourseFragment$onViewCreated$1$1.invokeSuspend(NewCourseFragment.kt:58) 
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) 
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) 
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571) 
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750) 
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678) 
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665) 

我的ViewModel是:

class CourseViewModel(val repository: CourseRepository): ViewModel(){

在我称之为协程的片段中,我这样声明它:私人val CourseViewModel: CourseViewModel by active ityViewModels()

共有1个答案

赵健柏
2023-03-14

首先,在这种情况下,您可能不需要用协程来混淆您的片段代码。您的ViewModel和/或存储库是更好的候选者,因为它们负责您应用程序的所谓业务逻辑。因此,理想情况下,将您的ViewModel函数更改为使用viewModelScope.launch(Dispatcher. IO),然后您的片段代码可以简单地为:

binding.button.setOnClickListener {
    courseViewModel.insertCourse(getData())
    Navigation.findNavController(it).popBackStack()
}

现在,关于ViewModel,您说您将其声明为:

class CourseViewModel(val repository: CourseRepository): ViewModel()

但是,默认的ViewModelProvider(activityViewModels()和viewModels()使用它来创建ViewModel)只会实例化一个零参数ViewModel,这解释了您看到的错误。(旁注:谷歌目前关于所有这些工作原理的文档非常糟糕;没有更好的说法。)

如果希望将存储库保留为参数,则需要创建自定义ViewModelFactory,以便ViewModelProvider知道如何实例化它。这个Android Kotlin Fundamentals codelab有一个如何创建的示例。

作为替代方案,您可以在Hilt和Jetpack中使用依赖注入,如下所述。

 类似资料:
  • 每当我请求权限时,我的应用程序就会崩溃。作为清单标记的子项,我在清单中定义了正确的使用权限。它没有给出任何错误,只是一个弹出窗口说包安装程序已经停止,监视器中有一行说“sendUserActionEvent()mView==null”,我不确定这与崩溃有关。 这是我请求权限的片段: 最低sdk设置为23,在三星Galaxy S7上进行测试。 你可以在这里看到完整的代码https://github.

  • 我使用的是IntelliJIDEA CE edition(11.0.4)的最新版本。有一件事我在任何地方都找不到,它阻碍了我对Java/Spring的进一步改进。 控制器: 类:导入com.example.demo.interfaces.ISave; 类接口: 没什么特别的,只是为了掌握Spring和Java。 在我的控制器里,当我试图使用 我收到一个阻止应用启动的错误。以下是错误: 任务应用程序

  • 我创建了一个应用程序,在Android marshmallow中崩溃,而在under版本中我的应用程序正常工作。 这怎么可能?这是我的清单代码: 这是分级代码: 我读到你必须在代码中修改一些东西,使其与AndroidMarshmallow兼容。 我该如何解决问题呢?

  • 最近,我通过学习CodeLabs教程学习了kotlin coroutine。经过一些实践,我想知道我是否可以用java编写相同的代码。首先,我在MyKotlinFragment中编写了一个简单的kotlin代码。kt文件如下: 在我的片段中调用了;它起作用了。 接下来,我打开了一个名为MyRoutineFragment的java文件。java在同一个项目中,但我无法让它工作。 我无法将第一个文件转

  • 3 CoreFoundation CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION+28 4 CoreFoundation__CFrunloopdoTimer+880 5 CoreFoundation__CFrunloopdoTimers+276 10 Figment POS AppDelegate.Swift-第39行main+39 11