无法在新项目中创建 class ViewModel 的实例
Cannot create an instance of class ViewModel in the new project
我有两个不同的项目。在第一个中,我将 ViewModel 与我的 activity 和 Room 数据库一起使用。一切正常。然后我为不同的目的创建了新项目,并以完全相同的方式实例化了 ViewModel,但我的应用程序崩溃并出现此错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.MainViewModel
at android.app.ActivityThread.performLaunchActivity(Unknown Source:591)
at android.app.ActivityThread.handleLaunchActivity(Unknown Source:36)
at android.app.servertransaction.LaunchActivityItem.execute(Unknown Source:57)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(Unknown Source:99)
at android.app.servertransaction.TransactionExecutor.execute(Unknown Source:34)
at android.app.ActivityThread$H.handleMessage(Unknown Source:36)
at android.os.Handler.dispatchMessage(Unknown Source:21)
at android.os.Looper.loop(Unknown Source:207)
at android.app.ActivityThread.main(Unknown Source:107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
at com.android.internal.os.ZygoteInit.main(Unknown Source:274)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.MainViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.kazguiu.MainActivity.applyAdapterAndViewModel(MainActivity.kt:37)
at com.kazguiu.MainActivity.onCreate(MainActivity.kt:25)
at android.app.Activity.performCreate(Unknown Source:16)
at android.app.Activity.performCreate(Unknown Source:1)
at android.app.Instrumentation.callActivityOnCreate(Unknown Source:3)
at android.app.ActivityThread.performLaunchActivity(Unknown Source:368)
at android.app.ActivityThread.handleLaunchActivity(Unknown Source:36)
at android.app.servertransaction.LaunchActivityItem.execute(Unknown Source:57)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(Unknown Source:99)
at android.app.servertransaction.TransactionExecutor.execute(Unknown Source:34)
at android.app.ActivityThread$H.handleMessage(Unknown Source:36)
at android.os.Handler.dispatchMessage(Unknown Source:21)
at android.os.Looper.loop(Unknown Source:207)
at android.app.ActivityThread.main(Unknown Source:107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
at com.android.internal.os.ZygoteInit.main(Unknown Source:274)
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.MainViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
我在 activity 中像这样实例化 ViewModel:
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
applyAdapterAndViewModel()
}
private fun applyAdapterAndViewModel() {
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}
我的视图模型:
class MainViewModel(application: Application) : AndroidViewModel(application) {
private val exampleDao = Database.getDatabase(application).exampleDao()
private val repository = Repository(exampleDao)
fun getSubjects() = repository.getSubjects()
fun addSubjects(subject: Subjects) = viewModelScope.launch(Dispatchers.IO) {
repository.addSubject(subject)
}
}
这种ViewModel的使用方式和我之前的项目是一样的。唯一的区别是我当前的 gradle:
中有两个额外的依赖项
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
如果我删除它们,Android Studio 无法识别 ViewModelProvider,但我以前的项目中根本没有这些依赖项,我使用 LiveData 和 ViewModel 的方式完全相同(甚至导入是一样的)那里。那么,我该怎么办?
您的 ViewModel 需要一个参数 application: Application
,它只能通过使用 ViewModelFactory 来提供,如下所示:
ViewModelFactory
class MainViewModelFactory(
private val application: Application
) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(application) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
MainActivity
private fun applyAdapterAndViewModel() {
// Not so kotlinic
mainViewModel = ViewModelProvider(this,MainViewModelFactory(application)).get(MainViewModel::class.java)
}
此外,在 MainActivity 中,替换
private lateinit var mainViewModel: MainViewModel
与
private val viewModel by viewModels<MainViewModel> {
MainViewModelFactory(application) }
我有两个不同的项目。在第一个中,我将 ViewModel 与我的 activity 和 Room 数据库一起使用。一切正常。然后我为不同的目的创建了新项目,并以完全相同的方式实例化了 ViewModel,但我的应用程序崩溃并出现此错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.MainViewModel
at android.app.ActivityThread.performLaunchActivity(Unknown Source:591)
at android.app.ActivityThread.handleLaunchActivity(Unknown Source:36)
at android.app.servertransaction.LaunchActivityItem.execute(Unknown Source:57)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(Unknown Source:99)
at android.app.servertransaction.TransactionExecutor.execute(Unknown Source:34)
at android.app.ActivityThread$H.handleMessage(Unknown Source:36)
at android.os.Handler.dispatchMessage(Unknown Source:21)
at android.os.Looper.loop(Unknown Source:207)
at android.app.ActivityThread.main(Unknown Source:107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
at com.android.internal.os.ZygoteInit.main(Unknown Source:274)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.MainViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.kazguiu.MainActivity.applyAdapterAndViewModel(MainActivity.kt:37)
at com.kazguiu.MainActivity.onCreate(MainActivity.kt:25)
at android.app.Activity.performCreate(Unknown Source:16)
at android.app.Activity.performCreate(Unknown Source:1)
at android.app.Instrumentation.callActivityOnCreate(Unknown Source:3)
at android.app.ActivityThread.performLaunchActivity(Unknown Source:368)
at android.app.ActivityThread.handleLaunchActivity(Unknown Source:36)
at android.app.servertransaction.LaunchActivityItem.execute(Unknown Source:57)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(Unknown Source:99)
at android.app.servertransaction.TransactionExecutor.execute(Unknown Source:34)
at android.app.ActivityThread$H.handleMessage(Unknown Source:36)
at android.os.Handler.dispatchMessage(Unknown Source:21)
at android.os.Looper.loop(Unknown Source:207)
at android.app.ActivityThread.main(Unknown Source:107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
at com.android.internal.os.ZygoteInit.main(Unknown Source:274)
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.MainViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
我在 activity 中像这样实例化 ViewModel:
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
applyAdapterAndViewModel()
}
private fun applyAdapterAndViewModel() {
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}
我的视图模型:
class MainViewModel(application: Application) : AndroidViewModel(application) {
private val exampleDao = Database.getDatabase(application).exampleDao()
private val repository = Repository(exampleDao)
fun getSubjects() = repository.getSubjects()
fun addSubjects(subject: Subjects) = viewModelScope.launch(Dispatchers.IO) {
repository.addSubject(subject)
}
}
这种ViewModel的使用方式和我之前的项目是一样的。唯一的区别是我当前的 gradle:
中有两个额外的依赖项implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
如果我删除它们,Android Studio 无法识别 ViewModelProvider,但我以前的项目中根本没有这些依赖项,我使用 LiveData 和 ViewModel 的方式完全相同(甚至导入是一样的)那里。那么,我该怎么办?
您的 ViewModel 需要一个参数 application: Application
,它只能通过使用 ViewModelFactory 来提供,如下所示:
ViewModelFactory
class MainViewModelFactory(
private val application: Application
) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(application) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
MainActivity
private fun applyAdapterAndViewModel() {
// Not so kotlinic
mainViewModel = ViewModelProvider(this,MainViewModelFactory(application)).get(MainViewModel::class.java)
}
此外,在 MainActivity 中,替换
private lateinit var mainViewModel: MainViewModel
与
private val viewModel by viewModels<MainViewModel> {
MainViewModelFactory(application) }