// This is a super simplified example of how to use the new dagger.android framework // introduced in Dagger 2.10. For a more complete, in-depth guide to dagger.android // read https://proandroiddev.com/how-to-android-dagger-2-10-2-11-butterknife-mvp-part-1-eb0f6b970fd // For a complete codebase using dagger.android 2.11/2.12/2.13, butterknife 8.7/8.8, and MVP, // see https://github.com/vestrel00/android-dagger-butterknife-mvp // This example works with Dagger 2.11/2.12/2.13. Starting with Dagger 2.11, // @ContributesAndroidInjector was introduced removing the need to define @Subcomponent classes. // App.java // Could also extend DaggerApplication instead of implementing HasActivityInjector public class App extends Application implements HasActivityInjector { @Inject AppDependency appDependency; @Inject DispatchingAndroidInjector activityInjector; @Override public void onCreate() { super.onCreate(); DaggerAppComponent.create().inject(this); } @Override public AndroidInjector activityInjector() { return activityInjector; } } // AppModule.java @Module(includes = AndroidInjectionModule.class) abstract class AppModule { @PerActivity @ContributesAndroidInjector(modules = MainActivityModule.class) abstract MainActivity mainActivityInjector(); } // AppComponent.java @Singleton @Component(modules = AppModule.class) interface AppComponent { void inject(App app); } // MainActivity.java // Could also extend DaggerActivity instead of implementing HasFragmentInjector public final class MainActivity extends Activity implements HasFragmentInjector { @Inject AppDependency appDependency; // same object from App @Inject ActivityDependency activityDependency; @Inject DispatchingAndroidInjector fragmentInjector; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { AndroidInjection.inject(this); super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); if (savedInstanceState == null) { addFragment(R.id.fragment_container, new MainFragment()); } } @Override public final AndroidInjector fragmentInjector() { return fragmentInjector; } } // MainActivityModule.java @Module public abstract class MainActivityModule { @PerFragment @ContributesAndroidInjector(modules = MainFragmentModule.class) abstract MainFragment mainFragmentInjector(); } // MainFragment.java // Could also extend DaggerFragment instead of implementing HasFragmentInjector // Could instead extend DialogFragment to add DialogFragment capabilities. // DialogFragments may be embedded as regular fragments in a view of an Activity or Fragment // and may also be shown as a dialog or in an alert dialog. public final class MainFragment extends Fragment implements HasFragmentInjector { @Inject AppDependency appDependency; // same object from App @Inject ActivityDependency activityDependency; // same object from MainActivity @Inject FragmentDependency fragmentDepency; @Inject DispatchingAndroidInjector childFragmentInjector; @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // Perform injection here for versions before M as onAttach(*Context*) did not yet exist AndroidInjection.inject(this); } super.onAttach(activity); } @Override public void onAttach(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Perform injection here for M (API 23) due to deprecation of onAttach(*Activity*). AndroidInjection.inject(this); } super.onAttach(context); } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.main_fragment, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (savedInstanceState == null) { addChildFragment(R.id.child_fragment_container, new MainChildFragment()); } } @Override public final AndroidInjector fragmentInjector() { return childFragmentInjector; } } // MainFragmentModule.java @Module public abstract class MainFragmentModule { @PerChildFragment @ContributesAndroidInjector(modules = MainChildFragmentModule.class) abstract MainChildFragment mainChildFragmentInjector(); } // MainChildFragment.java public final class MainChildFragment extends Fragment { @Inject AppDependency appDependency; // same object from App @Inject ActivityDependency activityDependency; // same object from MainActivity @Inject FragmentDependency fragmentDepency; // same object from MainFragment @Inject ChildFragmentDependency childFragmentDepency; @Override public void onAttach(Context context) { AndroidInjection.inject(this); super.onAttach(context); } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.main_child_fragment, container, false); } } // MainChildFragmentModule.java @Module public abstract class MainChildFragmentModule { } // PerActivity.java @Scope @Retention(RetentionPolicy.RUNTIME) public @interface PerActivity { } // PerFragment.java @Scope @Retention(RetentionPolicy.RUNTIME) public @interface PerFragment { } // PerChildFragment.java @Scope @Retention(RetentionPolicy.RUNTIME) public @interface PerChildFragment { } // AppDependency.java @Singleton public final class AppDependency { @Inject AppDependency() { } } // ActivityDependency.java @PerActivity public final class ActivityDependency { @Inject ActivityDependency() { } } // FragmentDependency.java @PerFragment public final class FragmentDependency { @Inject FragmentDependency() { } } // ChildFragmentDependency.java @PerChildFragment public final class ChildFragmentDependency { @Inject ChildFragmentDependency() { } }