Dagger Reflect - sergei-lapin/pimp-my-gradle-recipes GitHub Wiki
Dagger Reflect is a nice way to, not without a compromise, boost annotation processing speed for your project.
Originally it is a library by Jake Wharton who is well known in Android dev community as a great specialist and libraries creator.
The core idea is to replace original dagger library and dagger compiler with reflection based analogues to boost the performance of day-to-day developer builds
Before you start, make sure that all of your Dagger components are created either via @Component.Factory or @Component.Builder, and that you custom Dagger related annotation classes @Qualifier, @MapKey, etc. are using RUNTIME retention
The library itself is offering two approaches:
- Partial reflection
- Full Reflection
Partial reflection
- Doesn't require code modification
- Generates component realisations that are basically proxy to reflection calls
Full reflection
- Requires code modification
- Complete skip of Dagger annotation processing
Applying to your project
From this point I'll focus on partial reflection approach as it seems more appropriate for day-to-day usage
Well, if we'd look at library's recommended way of applying it to your project dependencies
dependencies {
if (properties.containsKey('android.injected.invoked.from.ide')) {
debugAnnotationProcessor 'com.jakewharton.dagger:dagger-reflect-compiler:0.3.0'
debugApi 'com.jakewharton.dagger:dagger-reflect:0.3.0' // or debugImplementation
} else {
debugAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
}
releaseAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
api "com.google.dagger:dagger:$daggerVersion" // or implementation
}
er... It doesn't seem quite nice. And one might ask: is there a better way? Of course there is. Introducing Delect plugin, that requires you to only add few lines to root project's build.gradle file
buildscript {
classpath 'com.soundcloud.delect:delect-plugin:0.3.0'
}
apply plugin: 'com.soundcloud.delect'
And add dagger.reflect=true to your local ~/.gradle/gradle.properties file — you're done. Now your local builds will use dagger reflect under the hood. In case you need to run build without dagger reflect only once you could invoke it like that ./gradlew taskName -Pdagger.reflect=false.
Cons of using Dagger Reflect are pretty obvious:
- Compile time DI graph validation is gone
- A bit of impact on app's runtime performance
Despite the cons, main advantage that you get is ~75% speed up of your annotation processing (at least it was the case for projects that I've applied it to). And of course you shouldn't deliver it as a part of your production code and only use it for better engineer experience during day-to-day work