Dependency injection with Hilt

Hilt - це бібліотека ін'єкції залежностей для Android, яка зменшує шаблонність ручної ін'єкції залежностей у вашому проекті. Ручна ін'єкція залежностей вимагає від вас створення кожного класу та його залежностей вручну, а також використання контейнерів для повторного використання та керування залежностями.

Hilt забезпечує стандартний спосіб використання DI у вашому додатку, надаючи контейнери для кожного класу Android у вашому проекті та автоматично керуючи їхніми життєвими циклами. Hilt побудовано на основі популярної бібліотеки DI Dagger, щоб скористатися перевагами коректності під час компіляції, продуктивності під час виконання, масштабованості та підтримки Android Studio, які надає Dagger. Докладнішу інформацію наведено у статтях Hilt і Dagger.

Цей посібник пояснює основні концепції Hilt та створених ним контейнерів. Він також містить демонстрацію того, як перезавантажити існуючу програму для використання Hilt.

Adding dependencies

First, add the hilt-android-gradle-plugin plugin to your project's root build.gradle file:

plugins {
  ...
  id 'com.google.dagger.hilt.android' version '2.51.1' apply false
}

Then, apply the Gradle plugin and add these dependencies in your app/build.gradle file:

...
plugins {
  id 'kotlin-kapt'
  id 'com.google.dagger.hilt.android'
}

android {
  ...
}

dependencies {
  implementation "com.google.dagger:hilt-android:2.51.1"
  kapt "com.google.dagger:hilt-compiler:2.51.1"
}

// Allow references to generated code
kapt {
  correctErrorTypes true
}

Hilt uses Java 8 features. To enable Java 8 in your project, add the following to the app/build.gradle file:

android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

Hilt application class

Усі додатки, які використовують Hilt, повинні містити клас Application, який має анотацію @HiltAndroidApp.

@HiltAndroidApp запускає генерацію коду Hilt, включаючи базовий клас для вашого додатку, який слугує контейнером залежностей на рівні додатку.

@HiltAndroidApp
public class ExampleApplication extends Application { ... }

Створений компонент Hilt приєднується до життєвого циклу об'єкта Application і надає йому залежності. Крім того, він є батьківським компонентом програми, а це означає, що інші компоненти можуть отримати доступ до залежностей, які він надає.

Inject dependencies into Android classes

Після того, як Hilt налаштовано у вашому класі Application і доступний компонент рівня додатку, Hilt може надавати залежності іншим класам Android, які мають анотацію @AndroidEntryPoint:

@AndroidEntryPoint
public class ExampleActivity extends AppCompatActivity { ... }

Hilt наразі підтримує наступні класи Android:

  • Application (за допомогою @HiltAndroidApp)
  • ViewModel (за допомогою @HiltViewModel)
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver

Якщо ви анотуєте клас Android за допомогою @AndroidEntryPoint, ви також повинні анотувати класи Android, які від нього залежать. Наприклад, якщо ви анотуєте фрагмент, ви також повинні анотувати всі activities, де ви використовуєте цей фрагмент.

@AndroidEntryPoint генерує окремий компонент Hilt для кожного класу Android у вашому проекті. Ці компоненти можуть отримувати залежності від відповідних батьківських класів, як описано в розділі Component hierarchy.

Щоб отримати залежності від компонента, використовуйте анотацію @Inject для виконання ін'єкції полів:

@AndroidEntryPoint
public class ExampleActivity extends AppCompatActivity {

  @Inject
  AnalyticsAdapter analytics;
  ...
}

Класи, які ін'єктує Hilt, можуть мати інші базові класи, які також використовують ін'єкцію. Цим класам не потрібна анотація @AndroidEntryPoint, якщо вони є абстрактними.

Щоб дізнатися більше про те, в який життєвий цикл інжектується клас Android, див. статтю Component lifetimes.

Define Hilt bindings

Щоб виконати ін'єкцію полів, Hilt повинен знати, як отримати екземпляри необхідних залежностей від відповідного компонента. binding містить інформацію, необхідну для надання екземплярів типу як залежності.

Одним із способів надання інформації про зв'язування до Hilt є ін'єкція конструктора. Використовуйте анотацію @Inject на конструкторі класу, щоб вказати Hilt, як надати екземпляри цього класу:

public class AnalyticsAdapter {

  private final AnalyticsService service;

  @Inject
  AnalyticsAdapter(AnalyticsService service) {
    this.service = service;
  }
  ...
}

Параметри анотованого конструктора класу є залежностями цього класу. У прикладі AnalyticsAdapter має AnalyticsService як залежність. Отже, Hilt також повинен знати, як надавати екземпляри AnalyticsService.

Hilt modules

Іноді type не може бути введений в конструктор. Це може статися з різних причин. Наприклад, ви не можете приєднати інтерфейс за допомогою конструктора. Ви також не можете вставити тип, який вам не належить, наприклад, клас із зовнішньої бібліотеки. У цих випадках ви можете надати Hilt інформацію про прив'язку за допомогою модулів Hilt.

Модуль Hilt - це клас, який анотується за допомогою @Module. Як і модуль Dagger, він інформує Hilt про те, як надавати екземпляри певних типів. На відміну від модулів Dagger, ви повинні анотувати модулі Hilt за допомогою @InstallIn, щоб повідомити Hilt, в якому класі Android буде використовуватися або встановлюватися кожен модуль.

Залежності, які ви надаєте в модулях Hilt, доступні у всіх згенерованих компонентах, які пов'язані з класом Android, куди ви встановлюєте модуль Hilt.

Inject interface instances with @Binds

Розглянемо приклад AnalyticsService. Якщо AnalyticsService є інтерфейсом, то ви не можете вставити в нього конструктор. Замість цього надайте Hilt інформацію про зв'язування, створивши абстрактну функцію з анотацією @Binds всередині модуля Hilt.

Анотація @Binds вказує Hilt, яку реалізацію використовувати, коли потрібно надати екземпляр інтерфейсу. Анотована функція надає Hilt наступну інформацію:

  • Тип повернення функції повідомляє Hilt, який інтерфейс функція надає екземпляри.
  • Параметр функції повідомляє Hilt, яку реалізацію слід надати.

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