无法从非@Nullable @Provides方法错误

时间:2017-06-22 02:13:44

标签: android android-fragments dependency-injection dagger-2

我有一个名为ViewModelModule的模块。就是这样:

@Module(includes = RepositoryModule.class)
public class ViewModelModule {

    StepListFragment stepListFragment;

    StepViewFragment stepViewFragment;

    @Provides
    public StepListFragment getStepListFragment() {
        return stepListFragment;
    }

    @Provides
    public StepViewFragment getStepViewFragment() {
        return stepViewFragment;
    }

    public ViewModelModule(StepListFragment stepListFragment) {
        this.stepListFragment = stepListFragment;
    }

    public ViewModelModule(StepViewFragment stepViewFragment) {
        this.stepViewFragment = stepViewFragment;
    }

    @Provides
    IngredientsViewModel ingredientsViewModel(StepListFragment stepListFragment, RecipesRepository repository) {
        return ViewModelProviders.of(stepListFragment, new ViewModelProvider.Factory() {
            @Override
            public <T extends ViewModel> T create(Class<T> modelClass) {
                return (T) new IngredientsViewModel(repository);
            }
        }).get(IngredientsViewModel.class);
    }

    @Provides
    StepsViewModel stepsViewModel(StepViewFragment stepViewFragment, RecipesRepository repository) {
        return ViewModelProviders.of(stepViewFragment, new ViewModelProvider.Factory() {
            @Override
            public <T extends ViewModel> T create(Class<T> modelClass) {
                return (T) new StepsViewModel(repository);
            }
        }).get(StepsViewModel.class);
    }

}

我将提供所有的ViewModules组件。但不是在同一时刻。

每个片段都有一个组件:

@Component(modules = {RepositoryModule.class, ContextModule.class, ViewModelModule.class})
public interface StepListComponent {
    void inject (StepListFragment stepListFragment);
}



@Component(modules = {RepositoryModule.class, ContextModule.class, ViewModelModule.class})

public interface StepViewComponent {
    void inject (StepViewFragment stepViewFragment);
}

在第一时间显示StepListFragment,我按如下方式实例化组件:

DaggerStepListComponent.builder()
        .applicationModule(new ApplicationModule(this.getActivity().getApplication()))
        .contextModule(new ContextModule(this.getActivity()))
        .viewModelModule(new ViewModelModule(this)).build().inject(this);

正如你在条款末尾看到的,我注入了片段。

之后,当我启动另一个片段时,我会做同样的事情。但当它调用上面的代码时,我收到了这个错误:

Caused by: java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method

当然,错误原因是我还没有实例化StepViewFragment stepViewFragment;但我现在不想使用它,所以它不会引起问题。

我尝试添加@Nullable子句,如下所示:

@Nullable
@Provides
public StepListFragment getStepListFragment() {
    return stepListFragment;
}

@Nullable
@Provides
public StepViewFragment getStepViewFragment() {
    return stepViewFragment;
}

然后我收到编译时错误:

    Error:(15, 10) error: StepListFragment is not nullable, but is being provided by @android.support.annotation.Nullable @Provides 
com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.steps.StepListFragment com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.di.ViewModelModule.getStepListFragment()
    at:     com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.steps.StepListFragment is injected at
    com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.di.ViewModelModule.ingredientsViewModel(stepListFragment, …)
    com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.ingredients.IngredientsViewModel is injected at
    com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.steps.StepListFragment.ingredientsViewModel
    com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.steps.StepListFragment is injected at
    com.github.alexpfx.udacity.nanodegree.android.baking_app.step.master.di.StepListComponent.inject(stepListFragment)

所以问题是:有没有办法通过使用相同的模块保持配置来解决这个问题,还是应该将每个@Provides分离到各自的模块中?这是一个好习惯吗?

1 个答案:

答案 0 :(得分:1)

片段不应该是ViewModel的依赖项 - ViewModel应该具有比Fragment更大的范围。

请参阅enter image description here,其中包含使用Dagger 2的Android架构组件的示例项目。

相关问题