使用Dagger 2的Android生命周期库ViewModel [英] Android lifecycle library ViewModel using dagger 2
问题描述
I have a ViewModel class just like the one defined in the Connecting ViewModel and repository section of Architecture guide. When I run my app I get a runtime exception. Does anyone know how to get around this? Should I not be injecting the ViewModel? Is there a way to tell the ViewModelProvider
to use Dagger to create the model?
public class DispatchActivityModel extends ViewModel {
private final API api;
@Inject
public DispatchActivityModel(API api) {
this.api = api;
}
}
原因:java.lang.InstantiationException:java.lang.Class没有零参数构造函数 在java.lang.Class.newInstance(本机方法) 在android.arch.lifecycle.ViewModelProvider $ NewInstanceFactory.create(ViewModelProvider.java:143) 在android.arch.lifecycle.ViewModelProviders $ DefaultFactory.create(ViewModelProviders.java:143) 在android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:128) 在android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:96) 在com.example.base.BaseActivity.onCreate(BaseActivity.java:65) 在com.example.dispatch.DispatchActivity.onCreate(DispatchActivity.java:53) 在android.app.Activity.performCreate(Activity.java:6682) 在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619)在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727) 在android.app.ActivityThread.-wrap12(ActivityThread.java) 在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1478) 在android.os.Handler.dispatchMessage(Handler.java:102) 在android.os.Looper.loop(Looper.java:154) 在android.app.ActivityThread.main(ActivityThread.java:6121)
Caused by: java.lang.InstantiationException: java.lang.Class has no zero argument constructor at java.lang.Class.newInstance(Native Method) at android.arch.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:143) at android.arch.lifecycle.ViewModelProviders$DefaultFactory.create(ViewModelProviders.java:143) at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:128) at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:96) at com.example.base.BaseActivity.onCreate(BaseActivity.java:65) at com.example.dispatch.DispatchActivity.onCreate(DispatchActivity.java:53) at android.app.Activity.performCreate(Activity.java:6682) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1478) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6121)
推荐答案
您需要实现自己的ViewModelProvider.Factory
.由Google创建的一个示例应用程序演示了如何将Dagger 2与ViewModels连接起来. LINK .您需要这5件事:
You need to implement your own ViewModelProvider.Factory
. There is an example app created by Google demonstrating how to connect Dagger 2 with ViewModels. LINK. You need those 5 things:
在ViewModel中:
In ViewModel:
@Inject
public UserViewModel(UserRepository userRepository, RepoRepository repoRepository) {
定义注释:
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
在ViewModelModule中:
In ViewModelModule:
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(UserViewModel.class)
abstract ViewModel bindUserViewModel(UserViewModel userViewModel);
在片段中:
@Inject
ViewModelProvider.Factory viewModelFactory;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);
工厂:
@Singleton
public class GithubViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public GithubViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
这篇关于使用Dagger 2的Android生命周期库ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!