/Dagger-Hilt-Playerground

A playground for learning dagger hilt on android

Primary LanguageKotlin

Dagger Hilt

Playground for learning how to use Hilt. A new way to incorporate Dagger dependency injection into an Android application.

Examples

Below is a list of examples.

I will be making video lectures using the gists below as examples.

  1. Preparing to use Hilt
  2. Field injecting a class with no dependencies. You own that class.
  3. Scopes and the "tier-like" system
  4. Dependencies that require dependencies (Concrete classes that you own)
  5. Some things can't be constructor-injected. What is the solution?
  6. Hilt Modules, Binds and Provides
  7. Multiple Bindings of the same type

NOTE This is not how I would build out the architecture normally. I greatly simplified this for beginners. See Simple Network & Cache Use-case for a Clean Architecture Implementation of the same thing.

  1. Retrieve data from open-api.xyz with Retrofit
  2. Cache data with Room
  3. Display cached data in UI
  1. Retrieve data from open-api.xyz with Retrofit
  2. Cache data with Room
  3. Display cached data in UI
  1. How to do fragment constructor injection with Hilt.

Guide:

https://developer.android.com/training/dependency-injection/hilt-testing

Important points:

  1. Dependencies
    1. Hilt
      • androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
      • kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
    2. launchFragmentInContainer
      • debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
  2. Test classes
    • Annotate with @HiltAndroidTest. Example
    • Include HiltAndroidRule. Example
  3. HiltTestApplication
    • Hilt automatically generates a HiltTestAppliaction. But it requires a custom Test Runner (see next point)
  4. Custom Test Runner
  5. Field Injection
    • Requres hiltRule.inject() in @Before function of test class. Example
  6. Test Fakes
    1. Method 1: Replacing a Module
      1. Uninstall the module in the test class
        • @UninstallModules(AnalyticsModule::class). Example
      2. Create a new module within the test class that replaces the old module. Example
    2. Method 2: @BindValue
  7. Custom Application for testing
    • Guide
    • I guess you might have to do this if one of your dependencies requires your custom Application class. But I think you could probably work-around this.
  8. Multiple Test rules
    • Guide
    • I didn't know this was an issue? Never encountered this.
  9. launchFragmentInContainer
    • launchFragmentInContainer does not work with Hilt because the activity it creates is not annotated with @AndroidEntryPoint. So there is a work-around:
    • Guide
    • launchFragmentInHiltContainer work-around:
      1. Create HiltExt.kt
        • NOTE One short-coming of this work-around is you cannot specify a FragmentFactory to the function. I made a slight modification so you can. That way you can do constructor injection. Modified HiltExt.kt
      2. Create /debug/HiltTestActivity.kt
      3. Create /debug/AndroidManifest.xml
      4. Launch the fragment: val scenario = launchFragmentInHiltContainer<MainFragment>( factory = fragmentFactory )

Issues

I got this weird error:

Could not determine the dependencies of task ':app:processDebugAndroidTestManifest'.
> Could not resolve all task dependencies for configuration ':app:debugAndroidTestRuntimeClasspath'.
   > Could not resolve com.google.code.findbugs:jsr305:{strictly 3.0.1}.
     Required by:
         project :app
      > Cannot find a version of 'com.google.code.findbugs:jsr305' that satisfies the version constraints: 
           Dependency path 'DaggerHiltPlayground:app:unspecified' --> 'androidx.test.espresso:espresso-core:3.2.0' --> 'com.google.code.findbugs:jsr305:2.0.1'
           Constraint path 'DaggerHiltPlayground:app:unspecified' --> 'com.google.code.findbugs:jsr305:{strictly 3.0.1}' because of the following reason: debugRuntimeClasspath uses version 3.0.1
           Dependency path 'DaggerHiltPlayground:app:unspecified' --> 'com.google.dagger:hilt-android-testing:2.28-alpha' --> 'com.google.code.findbugs:jsr305:3.0.1'
           Dependency path 'DaggerHiltPlayground:app:unspecified' --> 'com.google.dagger:hilt-android:2.28-alpha' --> 'com.google.code.findbugs:jsr305:3.0.1'
           Dependency path 'DaggerHiltPlayground:app:unspecified' --> 'com.google.dagger:hilt-android-testing:2.28-alpha' --> 'com.google.guava:guava:27.1-jre' --> 'com.google.code.findbugs:jsr305:3.0.2'

Solution

invertase/react-native-firebase#1954

I just added this to build.gradle and everything worked fine:

android {
    ... 

    configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.0'
    }
}