无法创建 class ViewModel 的实例
Cannot create an instance of class ViewModel
我正在尝试使用 Android 架构组件编写一个示例应用程序,但即使在尝试了几天之后我也无法让它工作。它给了我上述异常。
生命周期所有者:-
public class MainActivity extends LifecycleActivity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_user);
PostViewModel viewModel = ViewModelProviders.of(this).get(PostViewModel.class);
viewModel.loadPosts();
viewModel.getPost().observe(this, new Observer<Post>() {
@Override
public void onChanged(@Nullable Post post) {
if(post != null) {
textView.setText(post.toString());
}
}
});
}
}
视图模型:-
public class PostViewModel extends ViewModel {
private MediatorLiveData<Post> post;
private PostRepository postRepo;
PostViewModel() {
post = new MediatorLiveData<>();
postRepo = new PostRepository();
}
public LiveData<Post> loadPosts() {
post.addSource(postRepo.getPost(),
post -> this.post.setValue(post)
);
return post;
}
@NonNull
public LiveData<Post> getPost() {
return post;
}
}
构造你的构造函数public
.
这对我来说不是很明显,但是当我收到这个错误时,我通过创建一个 public 构造函数解决了它。我的构造函数派生自 Android Developer 示例,并包含存储库作为参数。创建一个没有参数的空的附加构造函数并让它 public 解决了这个问题。
也就是说,在你的情况下
public PostViewModel() {}
制作 class 和构造函数 public 它解决了我的问题。
确保您的 ViewModel
构造函数只有一个参数,即 Application
.
示例:
public YourViewModel(Application application) {
super(application);
...
如果您使用的是 Kotlin
,请确保将 build.gradle
中的任何 annotationProcessor
替换为 kapt
。
喜欢:
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
会变成
kapt "android.arch.persistence.room:compiler:$rootProject.roomVersion"
并添加
apply plugin: 'kotlin-kapt'
在 buidl.gradle
文件之上。
几乎没有理由抛出异常。我已经提到了其中的一些..
确保您的视图模型 class 是 public
确保您的视图模型 class 构造函数是 public
确保您已在 gradle 文件中添加依赖项
如果您使用房间和您添加的其他库,生命周期也一样..
如果您在视图模型中创建对象任何其他依赖 class
class 构造函数。其他 class 可以抛出错误来创建
视图模型实例
- 大多数情况下,Solution 将 Class 和 Constructor Public 作为其他答案
- 也可能是运行时错误,如果列出了多种原因,请检查 Logcat 错误日志。
迁移到 AndroidX 后我得到了这个。
androidx.lifecycle:lifecycle-viewmodel:2.0.0-beta01
中存在错误,Proguard 删除了构造函数。
https://issuetracker.google.com/issues/112230489
通过升级到 2.0.0 进行修复,并记得在需要时更新您的混淆器规则。
我的错误信息是这样的:
java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:202)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
......
Caused by: java.lang.NoSuchMethodException: <init> [class android.app.Application]
at java.lang.Class.getConstructor0(Class.java:2204)
at java.lang.Class.getConstructor(Class.java:1683)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
... 34 more
androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 539, 1167 and precision: 16, 16' on view 'with id: my.test:id/button_return_to_main_menu'.
at androidx.test.espresso.PerformException$Builder.build(PerformException.java:82)
at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:79)
.....
Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{my.custom.domain.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
从您的 ViewModel class.
扩展 AndroidViewModel
public class YourViewModel extends AndroidViewModel {
public YourViewModel(Application application) {
super(application);
//Todo: ...
}
}
如果您在 activity 中使用了视图模型,请检查您的 activity 是否扩展了 "DaggerAppCompatActivity"
例如
public class UserComments extends AppCompatActivity
将此更改为
public class UserComments extends DaggerAppCompatActivity
我正在使用这个例子android-arcuitecture-component BasicSample做一个新项目,遇到类似的错误日志,发现我没有更改应用程序名称
AndroidManifest.xml
那是我的错误,为了修复将应用程序名称设置为 de BasicApp,此 class 在示例中实现。
...
<application
android:name=".BasicApp"
android:allowBackup="false"
如果您的 PostViewModel class 是内部 class,请确保它的 public 和静态
在我的例子中,我需要使用 ListItemViewModelFactory 将参数传递给我的视图模型。
就我而言,原因是我试图过早地在我的片段中获取 ViewModel 的共享实例 - 在 activity 创建之前。当应用程序被杀死后恢复其状态时会发生什么。
先决条件:
- 我的 ViewModel 有一个 public 构造函数。
- 我的 ViewModel 有多个参数。但这绝对没问题,因为我使用 ViewModelFactory 来构建 ViewModel。
- 我的片段和 Activity shares the same instance of the ViewModel。换句话说:Activity 创建 ViewModel 并且片段稍后接收相同的实例。
activity中的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//factory is constructed using Dagger
val factory = App.get().components().appComponent.getMapViewModelFactory()
//activity creates the instance of MapViewModel
viewModel = ViewModelProviders.of(this, factory)[MapViewModel::class.java]
}
片段中的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//fragment receives the instance of MapViewModel
viewModel = ViewModelProviders.of(activity!!)[MapViewModel::class.java]
...
}
当我第一次打开应用程序时,一切正常:activity 创建了一个 ViewModel 实例;我打开 Fragment,它获取 ViewModel 的实例。但是当应用程序在被杀死后试图恢复它的状态时,它首先调用了 Fragment 的 onCreate 主体,然后是 Activity 的 onCreate 主体。那时,片段无法获取 ViewModel,因为 Activity 尚未创建它。
方案一:将fragment获取ViewModel时的代码从onCreate移到onViewCreated。这很好,因为我也观察了 onViewCreated 中的所有实时数据。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = activity?.run { ViewModelProviders.of(this)[MapViewModel::class.java] } ?: throw Exception("Invalid Activity")
viewModel.getSurveyDateLiveData().observe(viewLifecycleOwner, Observer<String> { dateTextView.text = it })
...
}
解决方案 2:
在调用 super.onCreate 之前,在 Activity.onCreate 中创建 ViewModel 的实例。在这种情况下,您可以在片段的 onCreate.
中获取 ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
val factory = App.get().components().appComponent.getMapViewModelFactory()
viewModel = ViewModelProviders.of(this, factory)[MapViewModel::class.java]
super.onCreate(savedInstanceState)
Timber.d("cc: onCreate: $this ")
}
解决方案 3:
如果您在 ViewModel 中注入存储库实例,请检查您是否使用 @Inject constructor(...): ViewModel()
注入存储库,而是 **@ViewModelInject constructor(...): ViewModel()**
我在 google 的 roomdb CodeLab 之后遇到了这个问题。解决方案正在更改以下内容。
已编辑
将以下构建依赖项添加到 Gradle 文件(截至 2020 年 2 月 22 日)
implementation 'androidx.fragment:fragment:1.2.2'
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
implementation 'androidx.lifecycle:lifecycle-service:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'
片段内导入
import androidx.lifecycle.ViewModelProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
正在创建视图模型。添加以下方法之一。
注意:我见过很多方法。我相信正确的方法是使用 getDefaultViewModelProviderFactory()
。但是我一直在用requireActivity()
.
new ViewModelProvider(requireActivity(),getDefaultViewModelProviderFactory()).get(YourViewModel.class);
|
new ViewModelProvider(requireActivity()).get(YourViewModel.class);
Deprecated
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc01'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0-rc01'
我的问题是 IDE 向我的 ViewModel class.
添加了一个“abstract”修饰符
就我而言,这是 gradle 依赖关系问题。
如果您使用的是实时数据,
build.gradle(Module.app)
没有
implementation 'android.arch.lifecycle:extensions:1.1.1'
kapt 'android.arch.lifecycle:common-java8:1.1.1'
使用这些
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
kapt 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
制作ViewModel class并构造public
如果您的视图模型的构造函数是 public 并且只接受应用程序,那么请确保您可以在没有 ViewModelProvider
的情况下创建自己的模型。错误信息可能更清楚:
val model = YouViewModel(app)
如果您使用的是 Hilt,请不要忘记添加这四个依赖项。
implementation "com.google.dagger:hilt-android:2.28-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
kapt "androidx.hilt:hilt-compiler:1.0.0-alpha01"
注意:- 如果缺少任何这些依赖项,您将收到 Cannot create an instance of class ViewModel
错误
请添加以下代码。它对我有用
val binding = FragmentLayoutBinding.inflate(inflater, container, false)
val viewModel = ViewModelProvider(
requireActivity(),
defaultViewModelProviderFactory
).get(MainViewModel::class.java)
如果您使用的是 Hilt
,请确保您的 activity/fragment 具有 @AndroidEntryPoint
注释
我是一名熟练的 Android 开发人员,我已经使用 ViewModel 100 多次,没有任何问题。今天我遇到了这个问题。花了几个小时浏览了各种 SO 帖子。没解决。
然后我看到我有ViewModel的包名包含new
。像这样:
com.myapp.myfeature.new.feature
我将 new
更改为 neww
以进行如下测试:
com.myapp.myfeature.neww.feature
成功了!我希望有人觉得它有用。
DggerHilt 也可能是原因,如果您正在使用它,请确保您的 activity/fragment
上有 @AndroidEntryPoint
注释。
如果您正在使用 Hilt 依赖注入,您可能错过了 @ViewModelInject。因为,Hilt 为视图模型提供了自己的注入。
在我的例子中,我使用了@Inject,因为它陷入了错误。
如果您使用的是 2.33-beta 及更高版本,请删除这些依赖项;
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0-beta01"
只保留这两个依赖
implementation "com.google.dagger:hilt-android:2.33-beta"
kapt "com.google.dagger:hilt-android-compiler:2.33-beta"
对于使用 Jetpack Compose、Navigation 和 Hilt 的用户
确保使用 hiltNavGraphViewModel
而不是 viewModel
。
这是由 androidx.hilt:hilt-navigation-compose
依赖项提供的。
docs 中有更多详细信息。
如果您在使用 @HiltViewModel 和使用 @Inject 后在 Kotlin Dagger Hilt 中遇到此问题,请确保您已更新所有 hilt 依赖项。
在您的 viewModel 之上添加 @HiltViewModel 。
对于与 Jetpack Compose 一起使用的 ViewModels
如果您在 组件 中使用带有 ViewModel
的 Jepack Compose。
@Preview
注释可能会导致此错误。这就是我的问题。
希望对大家有所帮助!
我通过这样做解决了同样的问题。
注意:- 我正在使用 Dagger 刀柄、Room 数据库、MVVM、数据绑定
添加了注释。
class AlertViewModel
@Inject
constructor(private val userRepository: AlertRepository) : ViewModel(){
val getList:LiveData<List<Alert>> get() =
userRepository.getList.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user:Alert){
viewModelScope.launch {
userRepository.insert(user)
}
}
}
到
@HiltViewModel // Added this annotation
class AlertViewModel
@Inject
constructor(private val userRepository: AlertRepository) : ViewModel(){
val getList:LiveData<List<Alert>> get() =
userRepository.getList.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user:Alert){
viewModelScope.launch {
userRepository.insert(user)
}
}
}
我在创建视图模型实例时遇到了不同的情况:
- 我在片段中请求实例。
- 我的 ViewModel 需要在构造函数上传递一个参数。
- 我没有使用依赖注入。
解决方案
在您的视图模型需要传递参数的情况下,您必须创建一个 ViewModelFactory 来定义您的实例
实践中的解决方案
- ViewModel Sample
class SharedViewModel(private val repository: UserRepository) : ViewModel() {
init {
viewModelScope.launch {
repository.refreshDataInDb()
}
}
}
- Creating ViewModel Factory
class ViewModelFactory(
private val repository: UserRepository
) : ViewModelProvider.NewInstanceFactory(){
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return SharedViewModel( repository as UserRepository) as T
}
}
- Creating ViewModel Instannce in a Fragment
private lateinit var factory: ViewModelFactory
private lateinit var searchViewModel: SharedViewModel
private lateinit var repository: UserRepository
repository = UserRepository()
factory = ViewModelFactory(repository)
searchViewModel = ViewModelProvider(requireActivity(), factory)[SharedViewModel::class.java]
嗯,这肯定会解决问题
首先确保你有这个依赖
//Room DB
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
然后删除 viewmodel 构造函数,然后创建 init 函数作为您的构造函数
public void init(Application application){
instance = new FirebaseDatabaseInstance();
databaseRepository = new DatabaseRepository(application);
allChatMembers = databaseRepository.getAllChatMembers();
}
那么这就解决了...
我正在尝试使用 Android 架构组件编写一个示例应用程序,但即使在尝试了几天之后我也无法让它工作。它给了我上述异常。
生命周期所有者:-
public class MainActivity extends LifecycleActivity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_user);
PostViewModel viewModel = ViewModelProviders.of(this).get(PostViewModel.class);
viewModel.loadPosts();
viewModel.getPost().observe(this, new Observer<Post>() {
@Override
public void onChanged(@Nullable Post post) {
if(post != null) {
textView.setText(post.toString());
}
}
});
}
}
视图模型:-
public class PostViewModel extends ViewModel {
private MediatorLiveData<Post> post;
private PostRepository postRepo;
PostViewModel() {
post = new MediatorLiveData<>();
postRepo = new PostRepository();
}
public LiveData<Post> loadPosts() {
post.addSource(postRepo.getPost(),
post -> this.post.setValue(post)
);
return post;
}
@NonNull
public LiveData<Post> getPost() {
return post;
}
}
构造你的构造函数public
.
这对我来说不是很明显,但是当我收到这个错误时,我通过创建一个 public 构造函数解决了它。我的构造函数派生自 Android Developer 示例,并包含存储库作为参数。创建一个没有参数的空的附加构造函数并让它 public 解决了这个问题。
也就是说,在你的情况下
public PostViewModel() {}
制作 class 和构造函数 public 它解决了我的问题。
确保您的 ViewModel
构造函数只有一个参数,即 Application
.
示例:
public YourViewModel(Application application) {
super(application);
...
如果您使用的是 Kotlin
,请确保将 build.gradle
中的任何 annotationProcessor
替换为 kapt
。
喜欢:
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
会变成
kapt "android.arch.persistence.room:compiler:$rootProject.roomVersion"
并添加
apply plugin: 'kotlin-kapt'
在 buidl.gradle
文件之上。
几乎没有理由抛出异常。我已经提到了其中的一些..
确保您的视图模型 class 是 public
确保您的视图模型 class 构造函数是 public
确保您已在 gradle 文件中添加依赖项 如果您使用房间和您添加的其他库,生命周期也一样..
如果您在视图模型中创建对象任何其他依赖 class class 构造函数。其他 class 可以抛出错误来创建 视图模型实例
- 大多数情况下,Solution 将 Class 和 Constructor Public 作为其他答案
- 也可能是运行时错误,如果列出了多种原因,请检查 Logcat 错误日志。
迁移到 AndroidX 后我得到了这个。
androidx.lifecycle:lifecycle-viewmodel:2.0.0-beta01
中存在错误,Proguard 删除了构造函数。
https://issuetracker.google.com/issues/112230489
通过升级到 2.0.0 进行修复,并记得在需要时更新您的混淆器规则。
我的错误信息是这样的:
java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:202)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
......
Caused by: java.lang.NoSuchMethodException: <init> [class android.app.Application]
at java.lang.Class.getConstructor0(Class.java:2204)
at java.lang.Class.getConstructor(Class.java:1683)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
... 34 more
androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 539, 1167 and precision: 16, 16' on view 'with id: my.test:id/button_return_to_main_menu'.
at androidx.test.espresso.PerformException$Builder.build(PerformException.java:82)
at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:79)
.....
Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{my.custom.domain.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
从您的 ViewModel class.
扩展 AndroidViewModelpublic class YourViewModel extends AndroidViewModel {
public YourViewModel(Application application) {
super(application);
//Todo: ...
}
}
如果您在 activity 中使用了视图模型,请检查您的 activity 是否扩展了 "DaggerAppCompatActivity"
例如
public class UserComments extends AppCompatActivity
将此更改为
public class UserComments extends DaggerAppCompatActivity
我正在使用这个例子android-arcuitecture-component BasicSample做一个新项目,遇到类似的错误日志,发现我没有更改应用程序名称
AndroidManifest.xml
那是我的错误,为了修复将应用程序名称设置为 de BasicApp,此 class 在示例中实现。
...
<application
android:name=".BasicApp"
android:allowBackup="false"
如果您的 PostViewModel class 是内部 class,请确保它的 public 和静态
在我的例子中,我需要使用 ListItemViewModelFactory 将参数传递给我的视图模型。
就我而言,原因是我试图过早地在我的片段中获取 ViewModel 的共享实例 - 在 activity 创建之前。当应用程序被杀死后恢复其状态时会发生什么。
先决条件:
- 我的 ViewModel 有一个 public 构造函数。
- 我的 ViewModel 有多个参数。但这绝对没问题,因为我使用 ViewModelFactory 来构建 ViewModel。
- 我的片段和 Activity shares the same instance of the ViewModel。换句话说:Activity 创建 ViewModel 并且片段稍后接收相同的实例。
activity中的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//factory is constructed using Dagger
val factory = App.get().components().appComponent.getMapViewModelFactory()
//activity creates the instance of MapViewModel
viewModel = ViewModelProviders.of(this, factory)[MapViewModel::class.java]
}
片段中的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//fragment receives the instance of MapViewModel
viewModel = ViewModelProviders.of(activity!!)[MapViewModel::class.java]
...
}
当我第一次打开应用程序时,一切正常:activity 创建了一个 ViewModel 实例;我打开 Fragment,它获取 ViewModel 的实例。但是当应用程序在被杀死后试图恢复它的状态时,它首先调用了 Fragment 的 onCreate 主体,然后是 Activity 的 onCreate 主体。那时,片段无法获取 ViewModel,因为 Activity 尚未创建它。
方案一:将fragment获取ViewModel时的代码从onCreate移到onViewCreated。这很好,因为我也观察了 onViewCreated 中的所有实时数据。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = activity?.run { ViewModelProviders.of(this)[MapViewModel::class.java] } ?: throw Exception("Invalid Activity")
viewModel.getSurveyDateLiveData().observe(viewLifecycleOwner, Observer<String> { dateTextView.text = it })
...
}
解决方案 2: 在调用 super.onCreate 之前,在 Activity.onCreate 中创建 ViewModel 的实例。在这种情况下,您可以在片段的 onCreate.
中获取 ViewModeloverride fun onCreate(savedInstanceState: Bundle?) {
val factory = App.get().components().appComponent.getMapViewModelFactory()
viewModel = ViewModelProviders.of(this, factory)[MapViewModel::class.java]
super.onCreate(savedInstanceState)
Timber.d("cc: onCreate: $this ")
}
解决方案 3:
如果您在 ViewModel 中注入存储库实例,请检查您是否使用 @Inject constructor(...): ViewModel()
注入存储库,而是 **@ViewModelInject constructor(...): ViewModel()**
我在 google 的 roomdb CodeLab 之后遇到了这个问题。解决方案正在更改以下内容。
已编辑
将以下构建依赖项添加到 Gradle 文件(截至 2020 年 2 月 22 日)
implementation 'androidx.fragment:fragment:1.2.2'
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
implementation 'androidx.lifecycle:lifecycle-service:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'
片段内导入
import androidx.lifecycle.ViewModelProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
正在创建视图模型。添加以下方法之一。
注意:我见过很多方法。我相信正确的方法是使用 getDefaultViewModelProviderFactory()
。但是我一直在用requireActivity()
.
new ViewModelProvider(requireActivity(),getDefaultViewModelProviderFactory()).get(YourViewModel.class);
|
new ViewModelProvider(requireActivity()).get(YourViewModel.class);
Deprecated
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc01'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0-rc01'
我的问题是 IDE 向我的 ViewModel class.
添加了一个“abstract”修饰符就我而言,这是 gradle 依赖关系问题。
如果您使用的是实时数据,
build.gradle(Module.app)
没有
implementation 'android.arch.lifecycle:extensions:1.1.1'
kapt 'android.arch.lifecycle:common-java8:1.1.1'
使用这些
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
kapt 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
制作ViewModel class并构造public
如果您的视图模型的构造函数是 public 并且只接受应用程序,那么请确保您可以在没有 ViewModelProvider
的情况下创建自己的模型。错误信息可能更清楚:
val model = YouViewModel(app)
如果您使用的是 Hilt,请不要忘记添加这四个依赖项。
implementation "com.google.dagger:hilt-android:2.28-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
kapt "androidx.hilt:hilt-compiler:1.0.0-alpha01"
注意:- 如果缺少任何这些依赖项,您将收到 Cannot create an instance of class ViewModel
错误
请添加以下代码。它对我有用
val binding = FragmentLayoutBinding.inflate(inflater, container, false)
val viewModel = ViewModelProvider(
requireActivity(),
defaultViewModelProviderFactory
).get(MainViewModel::class.java)
如果您使用的是 Hilt
,请确保您的 activity/fragment 具有 @AndroidEntryPoint
注释
我是一名熟练的 Android 开发人员,我已经使用 ViewModel 100 多次,没有任何问题。今天我遇到了这个问题。花了几个小时浏览了各种 SO 帖子。没解决。
然后我看到我有ViewModel的包名包含new
。像这样:
com.myapp.myfeature.new.feature
我将 new
更改为 neww
以进行如下测试:
com.myapp.myfeature.neww.feature
成功了!我希望有人觉得它有用。
DggerHilt 也可能是原因,如果您正在使用它,请确保您的 activity/fragment
上有 @AndroidEntryPoint
注释。
如果您正在使用 Hilt 依赖注入,您可能错过了 @ViewModelInject。因为,Hilt 为视图模型提供了自己的注入。
在我的例子中,我使用了@Inject,因为它陷入了错误。
如果您使用的是 2.33-beta 及更高版本,请删除这些依赖项;
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0-beta01"
只保留这两个依赖
implementation "com.google.dagger:hilt-android:2.33-beta"
kapt "com.google.dagger:hilt-android-compiler:2.33-beta"
对于使用 Jetpack Compose、Navigation 和 Hilt 的用户
确保使用 hiltNavGraphViewModel
而不是 viewModel
。
这是由 androidx.hilt:hilt-navigation-compose
依赖项提供的。
docs 中有更多详细信息。
如果您在使用 @HiltViewModel 和使用 @Inject 后在 Kotlin Dagger Hilt 中遇到此问题,请确保您已更新所有 hilt 依赖项。
在您的 viewModel 之上添加 @HiltViewModel 。
对于与 Jetpack Compose 一起使用的 ViewModels
如果您在 组件 中使用带有 ViewModel
的 Jepack Compose。
@Preview
注释可能会导致此错误。这就是我的问题。
希望对大家有所帮助!
我通过这样做解决了同样的问题。
注意:- 我正在使用 Dagger 刀柄、Room 数据库、MVVM、数据绑定
添加了注释。
class AlertViewModel
@Inject
constructor(private val userRepository: AlertRepository) : ViewModel(){
val getList:LiveData<List<Alert>> get() =
userRepository.getList.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user:Alert){
viewModelScope.launch {
userRepository.insert(user)
}
}
}
到
@HiltViewModel // Added this annotation
class AlertViewModel
@Inject
constructor(private val userRepository: AlertRepository) : ViewModel(){
val getList:LiveData<List<Alert>> get() =
userRepository.getList.flowOn(Dispatchers.Main)
.asLiveData(context = viewModelScope.coroutineContext)
fun insert(user:Alert){
viewModelScope.launch {
userRepository.insert(user)
}
}
}
我在创建视图模型实例时遇到了不同的情况:
- 我在片段中请求实例。
- 我的 ViewModel 需要在构造函数上传递一个参数。
- 我没有使用依赖注入。
解决方案 在您的视图模型需要传递参数的情况下,您必须创建一个 ViewModelFactory 来定义您的实例
实践中的解决方案
- ViewModel Sample
class SharedViewModel(private val repository: UserRepository) : ViewModel() {
init {
viewModelScope.launch {
repository.refreshDataInDb()
}
}
}
- Creating ViewModel Factory
class ViewModelFactory(
private val repository: UserRepository
) : ViewModelProvider.NewInstanceFactory(){
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return SharedViewModel( repository as UserRepository) as T
}
}
- Creating ViewModel Instannce in a Fragment
private lateinit var factory: ViewModelFactory
private lateinit var searchViewModel: SharedViewModel
private lateinit var repository: UserRepository
repository = UserRepository()
factory = ViewModelFactory(repository)
searchViewModel = ViewModelProvider(requireActivity(), factory)[SharedViewModel::class.java]
嗯,这肯定会解决问题
首先确保你有这个依赖
//Room DB
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
然后删除 viewmodel 构造函数,然后创建 init 函数作为您的构造函数
public void init(Application application){
instance = new FirebaseDatabaseInstance();
databaseRepository = new DatabaseRepository(application);
allChatMembers = databaseRepository.getAllChatMembers();
}
那么这就解决了...