当前位置: 首页 > 知识库问答 >
问题:

Android ViewModel没有零参数构造函数

侯和惬
2023-03-14

我通过本文档了解LiveData和ViewModel。在文档中,ViewModel类具有构造函数,

public class UserModel extends ViewModel {
  private MutableLiveData<User> user;

  @Inject UserModel(MutableLiveData<User> user) {
    this.user = user;
  }

  public void init() {
    if (this.user != null) {
      return;
    }
    this.user = new MutableLiveData<>();
  }

  public MutableLiveData<User> getUser() {
    return user;
  }
}

但是,当我运行代码时,会出现异常:

final UserViewModelviewModel = ViewModelProviders.of(this).get(UserViewModel.class);

原因:java.lang.运行时异常:无法创建类的实例UserViewModel原因:java.lang.实例异常:java.lang.类没有零参数构造函数

共有3个答案

慕翰学
2023-03-14

ViewModelFactory这将为我们提供一个正确的ViewModel从ViewModelModul

public class ViewModelFactory implements ViewModelProvider.Factory {
    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels;

    @Inject
    public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels) {
        this.viewModels = viewModels;
    }

    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        Provider<ViewModel> viewModelProvider = viewModels.get(modelClass);

        if (viewModelProvider == null) {
            throw new IllegalArgumentException("model class " + modelClass + " not found");
        }

        return (T) viewModelProvider.get();
    }
}

ViewModelModule负责将所有ViewModel类绑定到
映射中

@Module
public abstract class ViewModelModule {

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory viewModelFactory); 
    //You are able to declare ViewModelProvider.Factory dependency in another module. For example in ApplicationModule.

    @Binds
    @IntoMap
    @ViewModelKey(UserViewModel.class)
    abstract ViewModel userViewModel(UserViewModel userViewModel);
    
    //Others ViewModels
}

ViewModelKey是一个注释,用作地图中的键,看起来像

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
    Class<? extends ViewModel> value();
}

现在您可以创建ViewModel并满足图中所有必要的依赖关系

public class UserViewModel extends ViewModel {
    private UserFacade userFacade;

    @Inject
    public UserViewModel(UserFacade userFacade) { // UserFacade should be defined in one of dagger modules
        this.userFacade = userFacade;
    }
} 

实例化ViewModel

public class MainActivity extends AppCompatActivity {

    @Inject
    ViewModelFactory viewModelFactory;
    UserViewModel userViewModel;

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

        ((App) getApplication()).getAppComponent().inject(this);

        userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);

    }
}
@Singleton
@Component(modules = {ApplicationModule.class, ViewModelModule.class})
public interface ApplicationComponent {
    //
}

陈飞
2023-03-14

在使用ViewModelProviders初始化ViewModel的子类时,默认情况下,它希望您的UserModel类具有零参数构造函数。在您的情况下,构造函数具有参数MutableLiveData

解决这个问题的一种方法是为UserModel使用默认的无参数构造函数。

否则,如果要为ViewModel类创建非零参数构造函数,可能需要创建一个自定义的ViewModelFactory类来初始化ViewModel实例,该实例实现了ViewModelProvider。工厂接口。

我还没有尝试过这个,但是这里有一个链接到一个优秀的谷歌示例:github.com/googlesamples/android-architecture-components.具体来说,查看这个类GithubViewModelFactory.javaJava代码,这个类GithubViewModelFactory.kt相应的静态编程语言代码。

盖锦程
2023-03-14

在我使用HILT的情况下,它在片段上方缺少一个注释,该片段具有一个ViewModel:@AndroidEntryPoint

@AndroidEntryPoint
class BestFragment : Fragment() { 
....

当然,在您的ViewModel类中,您还需要使用HILT需要的注释:@ViewModelInject

class BestFragmentViewModel @ViewModelInject constructor(var userManager: UserManager) : ViewModel() {
....
}
 类似资料:
  • 我正在尝试使用recyclerview和room库创建一个简单的ToDoList应用程序。在使用room和mvvm架构方面,我正在遵循android开发者代码实验室,我似乎遇到了困难。我已经设置了应用程序的每一层,但在尝试使用ViewModelProvider实例化ViewModel时出现了一个错误。下面是我的ViewModel类中的代码。 } 下面是我试图初始化ViewModel的main片段中

  • 我是新的Android和Java,并试图使基于位置的应用程序。 编辑 我做了一个非常非常简单的测试代码,得到了同样的错误。这是java: 我也犯了同样的错误。以下是我的应用程序级构建中的依赖项。格雷德尔: 原帖 我试图使用ViewModel和LiveData来更新用户位置,因为我知道这是生命周期感知的最佳方式。我有一个默认的地图活动... 一个扩展LiveData以存储用户位置的类。。。 以及一个

  • 我正在使用并试图将我的导入我的类。 当使用ViewModel查看Google的hilt文档时,我们可以看到他们能够将注入到所述

  • 我想启动一项服务,我使用: 启动它: 我的应用崩溃后,logcat返回: java.lang.Class 在 android.app.活动线程.handle上没有零参数构造函数创建服务(活动线程.java:3201) 在 android.app.活动线程.-wrap5(活动线程.java) 在 android.app.活动线程$H.handleMessage(活动线程.java:1586) 在 a

  • 我试图在谷歌地图中显示一个位置地址,但当我为获取地址启动意向服务时,它将显示错误“无法实例化服务”。 我使用此链接显示位置地址。 这是我的代码: 在这里我开始意图服务:

  • 注:在标记为副本之前,请仔细阅读。我已经尝试了所有现有的答案。 我在用匕首2。 视图模型实例已在活动中成功创建,但当我从同一活动中打开BottomSheet对话框时,无法创建实例。 日志: 用户界面。搜索viewmodel。SearchViewModel