作者:淡忘那曾经的你_953 | 来源:互联网 | 2023-02-02 19:51
我正在关注此文档以了解LiveData和ViewModel.在doc中,ViewModel类具有构造函数,
public class UserModel extends ViewModel {
private MutableLiveData user;
@Inject UserModel(MutableLiveData user) {
this.user = user;
}
public void init() {
if (this.user != null) {
return;
}
this.user = new MutableLiveData<>();
}
public MutableLiveData getUser() {
return user;
}
}
但是,当我运行代码时,我得到异常:
final UserViewModelviewModel = ViewModelProviders.of(this).get(UserViewModel.class);
引起:java.lang.RuntimeException:无法创建类UserViewModel的实例引起:java.lang.InstantiationException:java.lang.Class没有零参数构造函数
Shahbaz Ahme..
44
在初始化ViewModel
using的子类时ViewModelProviders
,默认情况下它期望您的UserModel
类具有零参数构造函数.在你的情况下,你的构造函数有参数MutableLiveData user
解决此问题的一种方法是为您设置默认的无arg构造函数 UserModel
否则,如果您希望ViewModel类具有非零参数构造函数,则可能必须创建一个自定义ViewModelFactory
类来初始化ViewModel实例,该实例将实现ViewModelProvider.Factory
接口.
我还没有尝试过这个,但是这里有链接到google的优秀样本:github.com/googlesamples/android-architecture-components.具体来说,结帐此类GithubViewModelFactory.java用于Java代码,此类GithubViewModelFactory.kt用于相应的Kotlin代码
1> Shahbaz Ahme..:
在初始化ViewModel
using的子类时ViewModelProviders
,默认情况下它期望您的UserModel
类具有零参数构造函数.在你的情况下,你的构造函数有参数MutableLiveData user
解决此问题的一种方法是为您设置默认的无arg构造函数 UserModel
否则,如果您希望ViewModel类具有非零参数构造函数,则可能必须创建一个自定义ViewModelFactory
类来初始化ViewModel实例,该实例将实现ViewModelProvider.Factory
接口.
我还没有尝试过这个,但是这里有链接到google的优秀样本:github.com/googlesamples/android-architecture-components.具体来说,结帐此类GithubViewModelFactory.java用于Java代码,此类GithubViewModelFactory.kt用于相应的Kotlin代码
2> yoAlex5..:
ViewModelFactory
这将为我们提供一个正确的ViewModel ViewModelModule
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map, Provider> viewModels;
@Inject
public ViewModelFactory(Map, Provider> viewModels) {
this.viewModels = viewModels;
}
@Override
public T create(Class modelClass) {
Provider viewModelProvider = viewModels.get(modelClass);
if (viewModelProvider == null) {
throw new IllegalArgumentException("model class " + modelClass + " not found");
}
return (T) viewModelProvider.get();
}
}
ViewModelModule
负责将所有ViewModel类绑定到
Map, Provider> viewModels
@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);
}
}
并且不要伪造添加ViewModelModule
到modules
列表中
@Singleton
@Component(modules = {ApplicationModule.class, ViewModelModule.class})
public interface ApplicationComponent {
//
}