使用匕首的Android生命周期库ViewModel 2

我有一个ViewModel类,就像在Architecture指南的Connecting ViewModel和repository部分定义的一样。 当我运行我的应用程序,我得到一个运行时exception。 有谁知道如何解决这个问题? 我不应该注入ViewModel吗? 有没有办法告诉ViewModelProvider使用Dagger来创build模型?

 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(Native方法)上没有零参数构造函数在android.arch.lifecycle.ViewModelProvider $ NewInstanceFactory.create(ViewModelProvider.java:143)在android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:138)android.arch.lifecycle.ViewModelProviderrs $ 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: (android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727))上的android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619)上的android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) app.ActivityThread.-wrap12(ActivityThread.java)在android.app.ActivityT 在android.app.ActivityThread.main上的android.os.Looper.loop(Looper.java:154)android.os.Handler.dispatchMessage(Handler.java:102)hread $ H.handleMessage(ActivityThread.java:1478) (ActivityThread.java:6121)

Solutions Collecting From Web of "使用匕首的Android生命周期库ViewModel 2"

你需要实现你自己的ViewModelProvider.Factory 。 有一个由Google创build的示例应用程序演示了如何将Dagger 2与ViewModels连接起来。 LINK 。 你需要这4件事情:

在ViewModel中:

 @Inject public UserViewModel(UserRepository userRepository, RepoRepository repoRepository) { 

在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); } } } 

如果你不想使用罗伯特答案中提到的工厂,我相信还有第二种select。 这不一定是更好的解决scheme,但总是很好的select。

您可以使用默认构造函数保留viewModel,并注入您的依赖项,就像在系统创build的活动或其他元素的情况下一样。 例:

视图模型:

 public class ExampleViewModel extends ViewModel { @Inject ExampleDependency exampleDependency; public ExampleViewModel() { DaggerExampleComponent.builder().build().inject(this); } } 

零件:

 @Component(modules = ExampleModule.class) public interface ExampleComponent { void inject(ExampleViewModel exampleViewModel); } 

模块:

 @Module public abstract class ExampleModule { @Binds public abstract ExampleDependency bindExampleDependency(ExampleDependencyDefaultImplementation exampleDependencyDefaultImplementation); } 

干杯,Piotr

我想提供第三个选项,任何人都在这个问题上磕磕绊绊。 Dagger ViewModel库将允许您使用ViewModels以类似Dagger2的方式进行注入,并可select指定ViewModel的作用域。

它删除了大量的样板,并允许使用注释以声明方式注入ViewModel:

 @InjectViewModel(useActivityScope = true) public MyFragmentViewModel viewModel; 

它还需要less量的代码来设置一个模块,从中可以生成完全dependency injection的ViewModels,之后就像调用一样简单:

 void injectFragment(Fragment fragment, ViewModelFactory factory) { ViewModelInejectors.inject(frag, viewModelFactory); } 

在生成的ViewModelInjectors类上。

免责声明:这是我的图书馆,但我相信这也是这个问题的作者和其他人想要实现相同的事情的使用。