2017-06-22 14 views
1

ViewModelModuleという名前のモジュールがあります。これは次のとおりです。@ Nullable @Providesメソッドのエラーからnullを返すことはできません

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

} 

すべてのViewModuleコンポーネントが提供されます。しかし、同じ瞬間ではありません。 StepListFragmentが示されている

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

最初の瞬間に、私は以下のようにコンポーネントをインスタンス化:

Iは各断片に対して1つの成分を有するあなたが句の終わりに参照として

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

私はその断片を注入する。

その後、私が他の断片を始めると、私は同じことをします。それが呼び出したときでも上記のコードは、このエラーを受け取りました:

オフコースのエラーの原因は、私はまだ StepViewFragment stepViewFragmentをインスタンス化していなかったという事実である
Caused by: java.lang.NullPointerException: Cannot return null from a [email protected] @Provides method 

。しかし、私は今、それを使用したくないので、問題は発生しません。

私は以下のように@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

フラグメントは、ViewModelの依存性であってはなりません。ViewModelは、フラグメントのスコープよりも大きなスコープを持つと考えられます。

私の破片や活動は、射出ターゲットであるが、私はモジュールでそれを必要とするオブジェクトを初期化するためにそれらを提供する必要がダガー2.

+0

とAndroidのアーキテクチャコンポーネントを使用するサンプルプロジェクトをthis GitHub repoを参照してください。これは、ViewModelsの場合です。そのフラグメントはモジュール内でのみ提供されています... – alexpfx

+0

@alexpfx [この回答](https://stackoverflow.com/q/44270577/5241933)と特に[サンプルGitHubプロジェクト]へのリンクを見てくださいhttps://github.com/googlesamples/android-architecture-components) –

+0

いい例。私は後でそれを勉強します。 – alexpfx

関連する問題