无法创建ViewModel类的实例

Par*_*dam 41 android mvvm android-architecture-components

我正在尝试使用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());
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

视图模型: -

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Com*_*are 80

制作你的构造函数public.

  • 仍然在片段中得到错误,类和构造函数都已公开. (11认同)
  • @ParagKadam:Android Studio不知道生命周期组件需要构造函数是公共的.Android Studio只能通过显式代码引用看到它. (3认同)
  • 有趣的是它在调试模式下工作,但在发布模式下编译应用程序时崩溃。 (3认同)
  • 这么小的错误,却有如此大的影响。谢谢。 (2认同)
  • 我的构造函数是公共的,但我收到此错误:由java.lang.RuntimeException引起:无法在android.arch.lifecycle.ViewModelProvider $ NewInstanceFactory.create(ViewModelProvider .java:153),位于android.arch.lifecycle.ViewModelProvider $ AndroidViewModelFactory.create(ViewModelProvider.java:210),位于android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134),位于android.arch.lifecycle.ViewModelProvider。在com.randa.android中获取(ViewModelProvider.java:102)。 (2认同)

You*_* Qi 73

如果您正在使用Hilt,请确保您的活动/片段有@AndroidEntryPoint注释

  • 我正在使用 Dagger Hilt,这个答案节省了我很多时间,谢谢! (8认同)
  • 即使在放置 @AndroidEntryPoin 之后,我仍然收到 java.lang.RuntimeException: Cannot create an instance of class ViewModel (3认同)
  • 好吧@AndriiOmelchenko,您是否尝试过在 viewModel 构造函数中注入 Hilt?因为我相信这是大多数开发人员都会犯的一个无心错误,这将导致“无法创建类 ViewModel 的实例”在运行时崩溃。 (2认同)
  • 最新的 `@HiltViewModel` 在你的 viewModel 之上 (2认同)

Dun*_*Luk 23

对于使用 Jetpack Compose、Navigation 和 Hilt 的用户

确保使用hiltNavGraphViewModel代替viewModel

这是由androidx.hilt:hilt-navigation-compose依赖性提供的。

文档中有更多详细信息。


Rab*_*dka 20

添加@HiltViewModel到您的 viewModel 之上。


viv*_*vek 13

确保你的ViewModel构造函数只有一个参数,即Application.

例:

public YourViewModel(Application application) {
    super(application);
    ...
Run Code Online (Sandbox Code Playgroud)

  • 为什么 ViewModel 只能有一个 constr。范围? (3认同)

thi*_*tch 13

我在 google 的roomdb CodeLab之后遇到了这个问题。解决方案是更改以下内容。

已编辑

将以下构建依赖项添加到 Gradle 文件(截至 2/22/2020)

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'
Run Code Online (Sandbox Code Playgroud)

片段内的导入

import androidx.lifecycle.ViewModelProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
Run Code Online (Sandbox Code Playgroud)

创建视图模型。添加以下方法之一。

注意:我见过很多方法。我相信正确的方法是使用getDefaultViewModelProviderFactory(). 不过我一直在用requireActivity()

 new ViewModelProvider(requireActivity(),getDefaultViewModelProviderFactory()).get(YourViewModel.class);
Run Code Online (Sandbox Code Playgroud)

|

 new ViewModelProvider(requireActivity()).get(YourViewModel.class);

          
Run Code Online (Sandbox Code Playgroud)

ViewModelProvider 文档

已弃用

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc01'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0-rc01'
Run Code Online (Sandbox Code Playgroud)

  • 最新的 android 生命周期文档表示,生命周期扩展依赖项现已弃用 https://developer.android.com/jetpack/androidx/releases/lifecycle# 但是,如果我从 gradle 文件中删除该依赖项,我将收到无法创建当我启动应用程序时,出现类视图模型错误的实例。我尝试添加列为当前的所有其他依赖项,甚至是可选的依赖项,但如果没有生命周期扩展依赖项,它就无法工作。现在,我必须保留已弃用的依赖项。我仍在试图找出为什么在没有这种依赖性的情况下它会失败。 (2认同)

Max*_*Max 10

如果您使用的Kotlin一定要更换任何annotationProcessorbuild.gradlekapt

喜欢:

annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"

会变成

kapt "android.arch.persistence.room:compiler:$rootProject.roomVersion"

并添加

apply plugin: 'kotlin-kapt'buidl.gradle文件顶部。

使用Kotlin进行注释处理

  • @Eoghan 我出于完全相同的原因发布了答案,因为我花了很长时间才理解这个问题。但人们并不温柔,并且不断投反对票,哈哈,即使我已经明确提到你是否使用 kotlin。 (3认同)
  • 它解决了我的问题。它可能不是 java 的正确答案,但对于“无法在 Kotlin 中创建类 ViewModel 的实例”是正确的 (2认同)

Hoq*_*dul 9

抛出异常的理由很少。我提到了其中一些..

  1. 确保您的视图模型类是公开的

  2. 确保您的视图模型类构造函数是公共的

  3. 如果您使用房间和其他已添加的库,请确保您已在生命周期的 gradle 文件中添加了依赖项 ..

  4. 如果您在视图模型类构造函数中创建对象任何其他依赖类。其他类可以抛出错误来创建viewModel的实例

  • 非常适合第四点!!!在找到您的逐步解决方案后,它真的解决了我。 (2认同)

Bra*_*don 6

这对我来说并不是很明显,但是当遇到这个错误时,我通过创建一个公共构造函数来解决它。我的构造函数源自 Android Developer 示例,并包含 Repository 作为参数。创建一个没有参数的空构造函数并将其公开解决了这个问题。

即,在你的情况下

public PostViewModel() {}


Rah*_*hul 6

DggerHilt也可能是原因,如果您正在使用它,请确保上面activity/fragment@AndroidEntryPoint注释。


小智 5

公开类和构造函数它解决了我的问题。


Zee*_*ro0 5

从 ViewModel 类扩展AndroidViewModel 。

public class YourViewModel extends AndroidViewModel {

    public YourViewModel(Application application) {
        super(application);

        //Todo: ...
    }

}
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您在活动中使用了 viewmodel,请检查您的活动是否扩展了“DaggerAppCompatActivity”

例如

public class UserComments extends AppCompatActivity 
Run Code Online (Sandbox Code Playgroud)

将此更改为

public class UserComments extends DaggerAppCompatActivity
Run Code Online (Sandbox Code Playgroud)


Din*_*ith 5

如果您使用Hilt,您的活动或片段需要@AndroidEntryPoint注释,并且视图模型也需要@HiltViewModel注释。