无法创建ViewModel类的实例(无法启动activity ComponentInfo) 我在我的项目中使用MVVM、改型、LiveData,但在看到这些链接之前,我就遇到了这个错误 错误 这是我的ViewModel,我认为问题出在我的构造函数中 公共类HomeViewModel扩展了AndroidViewModel{ 私人电影制片厂电影制片厂; 公共HomeViewModel(@NonNull应用程序、上下文上下文、LifecycleOwner LifecycleOwner){ 超级(应用); movieRepository=新的movieRepository(生命周期所有者,上下文); } LiveData getMovies(){ 返回movieRepository.getMovies(); }} 存储库 public类MovieRepository扩展了BaseRepository{ 私人生命周期所有者生命周期所有者; 私人电影; 私人MovieDatabaseHelper MovieDatabaseHelper; 公共电影位置(LifecycleOwner LifecycleOwner,上下文){ this.lifecycleOwner=lifecycleOwner; movieApi=getRefughtHelper().getService(movieApi.class); movieDatabaseHelper=新的movieDatabaseHelper(上下文); } 公共LiveData getMovies(){ LiveData moviesLiveData=movieApi.getMovieList(); moviesLiveData.observe(lifecycleOwner,new Observer()){ @凌驾 更改后的公共void(@Nullable List movieArrayList){ movieDatabaseHelper.Save(movieArrayList); } }); 返回movieDatabaseHelper.getAll(); } } 活动课 公共类HomeActivity扩展了AppCompatActivity{ @凌驾 创建时受保护的void(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //错误就在这里 HomeViewModel HomeViewModel=ViewModelProviders.of(this.get)(HomeViewModel.class); homeViewModel.getMovies().observe(HomeActivity.this,new Observator()){ @凌驾 更改后的公共void(@Nullable List movieArrayList){ 字符串str=null; if(movieArrayList!=null){ str=Arrays.toString(movieArrayList.toArray()); } Log.e(“电影”,str); } }); }
} 我应该在我的项目和定制工厂中使用Dagger吗?引用: 子类必须有一个接受应用程序作为唯一参数的构造函数 您的构造函数不符合该要求 要么:无法创建ViewModel类的实例(无法启动activity ComponentInfo) 我在我的项目中使用MVVM、改型、LiveData,但在看到这些链接之前,我就遇到了这个错误 错误 这是我的ViewModel,我认为问题出在我的构造函数中 公共类HomeViewModel扩展了AndroidViewModel{ 私人电影制片厂电影制片厂; 公共HomeViewModel(@NonNull应用程序、上下文上下文、LifecycleOwner LifecycleOwner){ 超级(应用); movieRepository=新的movieRepository(生命周期所有者,上下文); } LiveData getMovies(){ 返回movieRepository.getMovies(); }} 存储库 public类MovieRepository扩展了BaseRepository{ 私人生命周期所有者生命周期所有者; 私人电影; 私人MovieDatabaseHelper MovieDatabaseHelper; 公共电影位置(LifecycleOwner LifecycleOwner,上下文){ this.lifecycleOwner=lifecycleOwner; movieApi=getRefughtHelper().getService(movieApi.class); movieDatabaseHelper=新的movieDatabaseHelper(上下文); } 公共LiveData getMovies(){ LiveData moviesLiveData=movieApi.getMovieList(); moviesLiveData.observe(lifecycleOwner,new Observer()){ @凌驾 更改后的公共void(@Nullable List movieArrayList){ movieDatabaseHelper.Save(movieArrayList); } }); 返回movieDatabaseHelper.getAll(); } } 活动课 公共类HomeActivity扩展了AppCompatActivity{ @凌驾 创建时受保护的void(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //错误就在这里 HomeViewModel HomeViewModel=ViewModelProviders.of(this.get)(HomeViewModel.class); homeViewModel.getMovies().observe(HomeActivity.this,new Observator()){ @凌驾 更改后的公共void(@Nullable List movieArrayList){ 字符串str=null; if(movieArrayList!=null){ str=Arrays.toString(movieArrayList.toArray()); } Log.e(“电影”,str); } }); },android,mvvm,android-architecture-components,android-viewmodel,Android,Mvvm,Android Architecture Components,Android Viewmodel,} 我应该在我的项目和定制工厂中使用Dagger吗?引用: 子类必须有一个接受应用程序作为唯一参数的构造函数 您的构造函数不符合该要求 要么: 从HomeViewModel中删除上下文上下文和生命周期所有者生命周期所有者构造函数参数,或 创建可以构建您的HomeViewModel实例的工厂,并将该工厂与ViewModelProviders.of()一起使用 基于,您可以这样做 class MvpApp : Application(){ companion object {
- 从
中删除HomeViewModel
和上下文上下文
构造函数参数,或生命周期所有者生命周期所有者
- 创建可以构建您的
实例的工厂,并将该工厂与HomeViewModel
ViewModelProviders.of()一起使用
- 基于,您可以这样做
class MvpApp : Application(){
companion object {
lateinit var application: Application
}
override fun onCreate() {
super.onCreate()
application = this
}
}
然后:
class ProfileViewModel: AndroidViewModel(MvpApp.application) {}
如果它能帮助某人。在我的例子中,Commonware告诉我的一切都是正确的,但是,我忘记了注入AppComponent
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// this line was missing
((BaseApplication) getApplication()).getAppComponent().inject(this);
super.onCreate(savedInstanceState);
}
HomeViewModel类中的需要扩展ViewModel类。
公共类MovieListViewModel扩展了ViewModel{
私有可变livedata数据;
私人电影定位电影模式;
公共MovieListViewModel(){
movieModel=新的MovieRepository();
}
公共void init(){
如果(this.data!=null){
//ViewModel是按片段创建的,因此
//我们知道用户ID不会改变
返回;
}
data=movieModel.getMovies();
}
公共可变LiveData getMovies(){
返回此.data;
}
}
还可以检查完整示例尝试添加以下内容:
private LiveData<Section[]> movies;
私有LiveData电影;
然后,改变这个:
LiveData<List<Movie>> getMovies() {
if(movies==null)
movies= movieRepository.getMovies();
return movies;
}
LiveData-getMovies(){
如果(电影==null)
movies=movieRepository.getMovies();
返回电影;
}
这对我来说很有效。正如其他答案中提到的,ViewModelProviders无法在ViewModel构造函数中插入所需的对象 如果您需要在没有任何工厂的情况下设置ViewModel快速且丑陋的,那么您可以使用Dagger2,在生成的
DaggerActivityComponent
中创建getYourViewModel()
方法,同时将这些对象放入您通过@Provides注释提供的构造函数中。然后只需将此字段添加到您的活动中:
@Inject
lateinit var viewmodel: YourViewModel
然后将它注入
OnCreate()
,就这样了NB:对于重和慢的ViewModels,请小心使用这种方法。如果您正在使用Kotlin,并且需要在ViewModel构造函数中注入依赖项,以便与存储库一样使用以获取数据(与我们使用Presenter层的方式相同),则需要执行以下操作
假设我们有一个ViewModel,它需要在构造函数中注入一个用例/交互器来从中获取数据
class MainViewModel(private val itemList:ItemListUseCase):ViewModel() {
...
}
当我们试图在活动/片段中实例化这个ViewModel时,我们倾向于这样做
片段示例
class MainFragment : Fragment() {
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainViewModel = requireActivity().run {
ViewModelProvider(this).get(MainViewModel::class.java)
}
...
}
}
当我们试图运行代码时,它将崩溃,出现RuntimeException
java.lang.RuntimeException:无法创建类的实例
com.gaston.example.viewmodel.MainViewModel。。。原因:
java.lang.InstanceionException:
java.lang.Class
没有零参数构造函数
这是因为当我们实例化我们的ViewModel
出现的第一件事是尝试直接从ViewModelProvider的.get()
方法注入它
ViewModelProvider(this).get(MainViewModel(ItemListUseCase()))
但是如果我们这样做,我们也会得到同样的错误
解决方案
我们需要了解的是
ViewModelProvider(this).get(MainViewModel::class.java)
ViewModelProvider()
正在尝试执行MainViewModel的实例,而不知道它的构造函数中需要依赖项
要解决此问题,我们需要让ViewModelProvier()
知道要注入哪个依赖项
为此,我们需要创建一个类来确保
@Inject
lateinit var viewmodel: YourViewModel
class MainViewModel(private val itemList:ItemListUseCase):ViewModel() {
...
}
class MainFragment : Fragment() {
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainViewModel = requireActivity().run {
ViewModelProvider(this).get(MainViewModel::class.java)
}
...
}
}
ViewModelProvider(this).get(MainViewModel(ItemListUseCase()))
ViewModelProvider(this).get(MainViewModel::class.java)
class ViewModelFactory(val requestItemData: ItemListUseCase):ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return modelClass.getConstructor(ItemListUseCase::class.java).newInstance(requestItemData)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainViewModel = requireActivity().run {
ViewModelProvider(this,ViewModelFactory(ItemListUseCase())).get(MainViewModel::class.java)
}
}