无法创建ViewModel类的实例

时间:2017-07-09 15:30:39

标签: 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());
                }
            }
        });
    }
}

视图模型: -

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;
    }
}

30 个答案:

答案 0 :(得分:52)

制作构造函数public

答案 1 :(得分:15)

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

答案 2 :(得分:9)

在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;

创建viewModel。添加以下方法之一。

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

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

|

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

ViewModelProvider Docs

已折旧

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc01'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0-rc01'

答案 3 :(得分:8)

请确保您的ViewModel的构造函数仅带有一个参数,即Application

示例:

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

答案 4 :(得分:6)

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

答案 5 :(得分:5)

如果您使用的是Kotlin,请确保将annotationProcessor中的任何build.gradle替换为kapt

赞:

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

将成为

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

并添加

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

Annotation Processing with Kotlin

答案 6 :(得分:4)

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

即,在你的情况下

public PostViewModel() {}

答案 7 :(得分:3)

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

确保使用 hiltNavGraphViewModel 而不是 viewModel

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

docs 中有更多详细信息。

答案 8 :(得分:3)

如果您使用的是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错误

答案 9 :(得分:2)

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

答案 10 :(得分:2)

没有什么理由抛出异常。我提到了其中一些。

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

  3. 确保已在网格文件中添加了以下项的依赖项:     如果您使用了房间和其他壁橱,也将获得生命周期。.

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

答案 11 :(得分:1)

如果您在 Kotlin Dagger Hilt 中遇到此问题,即使在使用 @HiltViewModel 并使用 @Inject 之后,请确保您已更新所有刀柄依赖项。

答案 12 :(得分:1)

如果您正在使用 Hilt 依赖注入,您可能已经错过了 @ViewModelInject。因为,Hilt 为视图模型提供了自己的注入。

在我的例子中,我使用了 @Inject 因为这陷入了错误。

答案 13 :(得分:1)

就我而言,这是一个依赖关系问题。

如果您正在使用Livedata,

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'

答案 14 :(得分:0)

在我的情况下,原因是我试图在创建活动之前不久将片段中ViewModel的共享实例获取。当应用程序被杀死后恢复其状态时,就会发生这种情况。

前提条件

  1. 我的ViewModel有一个公共构造函数。
  2. 我的ViewModel有多个参数。但这绝对好,因为我使用ViewModelFactory构造ViewModel。
  3. 我的片段和活动shares the same instance of the ViewModel。换句话说:Activity创建ViewModel,然后片段稍后接收相同的实例。

活动代码:

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]
    ...
}

当我第一次打开应用程序时,一切正常:活动创建ViewModel实例;我打开Fragment,它获取ViewModel的实例。但是,当应用程序被杀死后试图恢复其状态时,它首先调用Fragment的onCreate主体,然后调用Activity的onCreate主体。到那时,片段无法获取ViewModel,因为Activity尚未创建它。

解决方案1 ​​:当片段将ViewModel从onCreate移到onViewCreated时,移动代码。就像我在onViewCreated中观察所有liveData一样,这很好。

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 ")
}

答案 15 :(得分:0)

我有同样的问题,尝试了许多方法,最后我找到了它。这是我的BASE_URL:

public static final String BASE_URL = "https://ipsquotes.herokuapp.com/oidcs";

修改

 public static final String BASE_URL = "https://ipsquotes.herokuapp.com/oidcs/";

而且有效,很有趣,对:((.。我认为您应该检查BASE_URL以确保其格式正确

答案 16 :(得分:0)

  

创建一个没有参数且为空的附加构造函数   公开解决该问题。

答案 17 :(得分:0)

我的问题是IDE在ViewModel类中添加了“ 抽象”修饰符。

答案 18 :(得分:0)

对于我来说,我需要使用ListItemViewModelFactory来将参数传递给我的视图模型。

答案 19 :(得分:0)

设置ViewModal类并构造公共

答案 20 :(得分:0)

如果您的视图模型的构造函数是公共的,并且仅接受应用程序,那么请确保您可以在没有ViewModelProvider的情况下创建自己的模型。错误消息可能更加清晰:

val model = YouViewModel(app)

答案 21 :(得分:0)

如果您的PostViewModel类是一个内部类,请确保其公共和静态

答案 22 :(得分:0)

我正在使用此示例android-arcuitecture-component BasicSample来创建一个新项目,面临类似的错误日志,发现我没有更改申请名称

  

AndroidManifest.xml

那是我的错误,要修复aplicacion名称为de BasicApp,该类在示例中是实现。

...
<application
    android:name=".BasicApp"
    android:allowBackup="false"

答案 23 :(得分:0)

我是一位熟练的Android开发人员,并且使用ViewModel已有100多次,没有任何问题。今天我遇到了这个问题。花了几个小时,浏览了各种SO帖子。没解决。

然后我看到其中装有ViewModel的程序包名称包含new。像这样:

com.myapp.myfeature.new.feature

我将new更改为neww进行了如下测试: com.myapp.myfeature.neww.feature

成功了!我希望有人觉得它有用。

答案 24 :(得分:0)

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

例如

public class UserComments extends AppCompatActivity 

将此更改为

public class UserComments extends DaggerAppCompatActivity

答案 25 :(得分:0)

从ViewModel类扩展 AndroidViewModel

public class YourViewModel extends AndroidViewModel {

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

        //Todo: ...
    }

}

答案 26 :(得分:0)

如果您使用的是 2.33-beta 和 upper 版本,请删除这些依赖项;

OnPause

只保留这两个依赖

implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0-beta01"

答案 27 :(得分:0)

我在迁移到AndroidX后得到了这个。

androidx.lifecycle:lifecycle-viewmodel:2.0.0-beta01中存在一个错误,其中Proguard删除了构造函数。

https://issuetracker.google.com/issues/112230489

通过升级到2.0.0修复,并记住在需要时更新您的proguard规则。

我的错误消息如下:

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)

答案 28 :(得分:0)

  1. 大多数情况下,Solution都会将Class和Constructor公开为其他答案
  2. 这也可能是运行时错误,请检查Logcat错误日志,是否列出了多个原因。

答案 29 :(得分:-1)

请添加以下代码。对我有用

val binding = FragmentLayoutBinding.inflate(inflater, container, false)

val viewModel = ViewModelProvider(
            requireActivity(),
            defaultViewModelProviderFactory
            ).get(MainViewModel::class.java)