Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android_Dependency_Injection_with_Hilt.pdf

Yoyo Coder
December 11, 2020

 Android_Dependency_Injection_with_Hilt.pdf

Yoyo Coder

December 11, 2020
Tweet

More Decks by Yoyo Coder

Other Decks in Programming

Transcript

  1. class Car { private val engine = Engine() fun start()

    { engine.start() } } fun main(args: Array) { val car = Car() car.start() }
  2. class Car(private val engine: Engine) { fun start() { engine.start()

    } } fun main(args: Array) { val engine = Engine() val car = Car(engine) car.start() }
  3. Is DI hard in Android? • Framework classes are instantiated

    by the SDK • Factories added on API 28, not realistic
  4. DI Solution Golds • Opinionated • Easy to setup •

    Let’s us focus on what is important
  5. Hilt • Standardize DI in Android • Build on the

    top of Dagger • Tooling support • AndroidX Extensions
  6. interface AnalyticsService { fun analyticsMethods() } // Constructor-injected, because Hilt

    needs to know how to // provide instances of AnalyticsServiceImpl, too. class AnalyticsServiceImpl @Inject constructor( ... ) : AnalyticsService { ... } @Module @InstallIn(ActivityComponent::class) abstract class AnalyticsModule { @Binds abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl ): AnalyticsService }
  7. @Module @InstallIn(ActivityComponent::class) object AnalyticsModule { @Provides fun provideAnalyticsService ( //

    Potential dependencies of this type ): AnalyticsService { return Retrofit.Builder() .baseUrl( "https://example.com" ) .build() .create(AnalyticsService:: class.java) } }
  8. class ExampleViewModel @ViewModelInject constructor( private val repository: ExampleRepository, @Assisted private

    val savedStateHandle: SavedStateHandle ) : ViewModel() { ... } @AndroidEntryPoint class ExampleActivity : AppCompatActivity() { private val exampleViewModel: ExampleViewModel by viewModels() ... }
  9. class ExampleWorker @WorkerInject constructor( @Assisted appContext: Context, @Assisted workerParams: WorkerParameters,

    workerDependency: WorkerDependency ) : Worker(appContext, workerParams) { ... } @HiltAndroidApp class ExampleApplication : Application(), Configuration.Provider { @Inject lateinit var workerFactory: HiltWorkerFactory override fun getWorkManagerConfiguration() = Configuration.Builder() .setWorkerFactory(workerFactory) .build() }
  10. @HiltAndroidTest class SettingsActivityTest { @get:Rule var hiltRule = HiltAndroidRule(this) @Inject

    lateinit var analyticsAdapter: AnalyticsAdapter @Before fun init() { hiltRule.inject() } @Test fun `happy path`() { ... } }
  11. @UninstallModules(AnalyticsModule ::class) @HiltAndroidTest class SettingsActivityTest { @Module @InstallIn(ApplicationComponent ::class) abstract

    class TestModule { @Singleton @Binds abstract fun bindAnalyticsService ( fakeAnalyticsService : FakeAnalyticsService ): AnalyticsService } @BindValue @JvmField val analyticsService : AnalyticsService = FakeAnalyticsService () }
  12. class CustomTestRunner : AndroidJUnitRunner() { override fun newApplication(cl: ClassLoader?, name:

    String?, context: Context?): Application { return super.newApplication(cl, HiltTestApplication::class.java.name, context) } } ——————————————————————————————————————————————— android { defaultConfig { testInstrumentationRunner "com.example.android.dagger.CustomTestRunner" } }
  13. Alpha Annotation processors and code generation could make build slower

    Android Official Build on Dagger but easy to use IDE support Android lifecycle aware Build Type award Coexist with Dagger Cheatsheet - Good docs - Codelabs Pros Cos
  14. Learn more Dependency injection with Hilt Dagger & Hilt documentation

    Dagger & Hilt repository Migrating your Dagger app to Hilt