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.
Hilt Basics
I will be making video lectures using the gists below as examples.
- Preparing to use Hilt
- Field injecting a class with no dependencies. You own that class.
- Scopes and the "tier-like" system
- Dependencies that require dependencies (Concrete classes that you own)
- Some things can't be constructor-injected. What is the solution?
- Hilt Modules, Binds and Provides
- https://gist.github.com/mitchtabian/d06ee1d6445265adf00b087fc56708d8
- Teach in this order:
- ComplexMethod_VALID.kt
- ComplexMethod_INVALID.kt
- SimpleMethod.kt
- Multiple Bindings of the same type
Basic MVI Repository Pattern
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.
- Retrieve data from open-api.xyz with Retrofit
- Cache data with Room
- Display cached data in UI
Simple Network & Cache Use-case
- Retrieve data from open-api.xyz with Retrofit
- Cache data with Room
- Display cached data in UI
Fragment Constructor Injection with Hilt
- How to do fragment constructor injection with Hilt.
Instrumentation Testing
Guide:
https://developer.android.com/training/dependency-injection/hilt-testing
Important points:
- Dependencies
- Hilt
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
launchFragmentInContainer
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
- Hilt
- Test classes
HiltTestApplication
- Hilt automatically generates a
HiltTestAppliaction
. But it requires a custom Test Runner (see next point)
- Hilt automatically generates a
- Custom Test Runner
- You must create a custom test runner and specify in build.gradle
- Field Injection
- Requres
hiltRule.inject()
in@Before
function of test class. Example
- Requres
- Test Fakes
- Method 1: Replacing a Module
- Method 2:
@BindValue
- I can't get this to work...
@BindValue var myString: String = "gggf"
- Might be a kotlin thing? Maybe can't change final params? Not sure.
- https://developer.android.com/training/dependency-injection/hilt-testing#binding-new
- I can't get this to work...
- 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.
- Multiple Test rules
- Guide
- I didn't know this was an issue? Never encountered this.
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:- 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
- NOTE One short-coming of this work-around is you cannot specify a
- Create /debug/HiltTestActivity.kt
- Create /debug/AndroidManifest.xml
- Launch the fragment:
val scenario = launchFragmentInHiltContainer<MainFragment>( factory = fragmentFactory )
- Create
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'
}
}