Android 生命周期库 ViewModel 使用 dagger 2 [英] Android lifecycle library ViewModel using dagger 2

查看:34
本文介绍了Android 生命周期库 ViewModel 使用 dagger 2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ViewModel 类,就像在 架构指南.当我运行我的应用程序时,出现运行时异常.有谁知道如何解决这个问题?我不应该注入 ViewModel 吗?有没有办法告诉 ViewModelProvider 使用 Dagger 创建模型?

public class DispatchActivityModel extends ViewModel {私有的最终 API api;@注入公共调度活动模型(API api){this.api = api;}}

<块引用>

Caused by: java.lang.InstantiationException: java.lang.Class has no zero argument constructor在 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)

解决方案

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

在视图模型中:

@Injectpublic UserViewModel(UserRepository userRepository, RepoRepository repoRepository) {

定义注解:

@Documented@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@地图键@interface ViewModelKey {类价值();}

在 ViewModelModule 中:

@Module抽象类 ViewModelModule {@绑定@IntoMap@ViewModelKey(UserViewModel.class)抽象 ViewModel bindUserViewModel(UserViewModel userViewModel);

在片段中:

@InjectViewModelProvider.Factory viewModelFactory;@覆盖public void onActivityCreated(@Nullable Bundle savedInstanceState) {userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);

工厂:

@Singleton公共类 GithubViewModelFactory 实现了 ViewModelProvider.Factory {私人最终地图<类,提供者<视图模型>>创作者;@注入public GithubViewModelFactory(Map, Provider> creators) {this.creators = 创造者;}@SuppressWarnings("未选中")@覆盖public <T extends ViewModel>T 创建(类 模型类){提供者creator = creators.get(modelClass);如果(创建者 == 空){for (Map.Entry, Provider> entry : creators.entrySet()) {如果 (modelClass.isAssignableFrom(entry.getKey())) {创建者 = entry.getValue();休息;}}}如果(创建者 == 空){throw new IllegalArgumentException("未知模型类" + modelClass);}尝试 {返回(T)creator.get();} 捕获(异常 e){抛出新的运行时异常(e);}}}

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

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)

解决方案

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:

In ViewModel:

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

Define annotation:

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

In ViewModelModule:

@Module
abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(UserViewModel.class)
    abstract ViewModel bindUserViewModel(UserViewModel userViewModel);

In Fragment:

@Inject
ViewModelProvider.Factory viewModelFactory;

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);

Factory:

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

这篇关于Android 生命周期库 ViewModel 使用 dagger 2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆