You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Android MVVM开发出现无法创建ViewModel实例的错误

Android MVVM 下"无法创建ViewModel实例"报错的Java版解决方案

问题背景

开发者跟随教程使用Java实现MVVM架构的Android应用时,运行触发“无法创建ViewModel实例”的崩溃。由于同类问题的解答均为Kotlin编写,开发者不了解Kotlin语法也无法对应理解实现逻辑,因此单独寻求可直接参考的Java版本解决思路。
开发者已实现的相关代码如下:

MainActivity 实现

UserViewModel userViewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
    userViewModel.getAllUsers().observe(this, new Observer<List<User>>() {
        @Override
        public void onChanged(List<User> users) {
            //update recyclerview here
            Toast.makeText(MainActivity.this,"onChanged",Toast.LENGTH_LONG).show();
        }
    });
}

UserViewModel 实现

public class UserViewModel extends AndroidViewModel {
    private UserRepository repository;
    private LiveData<List<User>> allUsers;

    public UserViewModel(@NonNull Application application) {
        super(application);
        repository = new UserRepository(application);
        allUsers = repository.getAllUsers();
    }

    public void insert(User user) {
        repository.insert(user);
    }

    public LiveData<List<User>> getAllUsers() {
        return allUsers;
    }
}

UserRepository 实现

public class UserRepository {
    private UserDao userDao;
    private LiveData<List<User>> allUsers;

    public UserRepository(Application application) {
        UserDatabase database = UserDatabase.getInstance(application);
        userDao = database.userDao();
        allUsers = userDao.getAllUsers();
    }

    public void insert(User user) {
        new Thread(new InsertInBackground(userDao,user)).start();
    }

    public LiveData<List<User>> getAllUsers() {
        return allUsers;
    }

    private static class InsertInBackground implements Runnable {
        private UserDao userDao;
        private User user;

        public InsertInBackground(UserDao userDao, User user) {
            this.userDao = userDao;
            this.user = user;
        }

        @Override
        public void run() {
            userDao.insert(user);
        }
    }
}

报错根因

直接调用new ViewModelProvider(this)时,系统会使用内置的默认构造工厂,这个工厂仅支持反射创建无参构造的ViewModel实例。
而当前实现的UserViewModel继承了AndroidViewModel,构造方法需要传入Application类型参数,默认工厂无法提供这个参数,反射创建实例时就会抛出“无法创建ViewModel实例”的运行时错误。

修正方案(纯Java实现,无Kotlin依赖)

将MainActivity中初始化ViewModel的代码,替换为系统提供的AndroidViewModelFactory工厂实例即可——这个工厂已经内置了Application实例的获取逻辑,完全匹配你当前的ViewModel构造方法要求:
把原来的初始化代码:

userViewModel = new ViewModelProvider(this).get(UserViewModel.class);

替换为:

userViewModel = new ViewModelProvider(
        this,
        ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())
).get(UserViewModel.class);

额外注意事项

  • 确保项目引入的是AndroidX生命周期依赖,不要使用过时的android.arch.lifecycle旧依赖,否则可能出现类找不到的问题
  • 不需要自定义工厂类,上述系统提供的工厂已经可以覆盖所有继承AndroidViewModel的类的创建逻辑
  • 如果后续需要给ViewModel传入自定义的额外参数,再按需继承ViewModelProvider.Factory实现自定义工厂即可,当前场景下不需要额外编码

内容的提问来源于stack exchange,提问作者M.Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 19:06:03