Пълно ръководство за инжектиране на зависимости с Hilt на Android

  • Hilt опростява Dagger, като предоставя автоматични контейнери, съобразени с жизнения цикъл на Android.
  • Позволява разделяне на кода чрез инжектиране на конструктори, модули с @Provides и @Binds.
  • Управлявайте обхвата на инстанциите, като използвате специфични компоненти, като например SingletonComponent или ActivityComponent.
  • Улеснява разработването на мащабируеми и тестваеми архитектури, особено в среди с Jetpack Compose и MVVM.

Хилт Андроид

Ако разработвате Android приложения, вероятно сте се сблъсквали с необходимостта от по-добра организация на класовете си, за да предотвратите пълен хаос в проекта. Тук се намесва инжектирането на зависимости (dependency injection) - дизайнерски шаблон, който, макар първоначално да изглежда като черна магия, по същество е начин да се предоставят на всеки клас обектите, от които се нуждае, без класът да се налага самият да ги създава.

Hilt се появява, за да ни спаси от сложността на Dagger, предлагайки горен слой, който стандартизира вмъкването на зависимости . Чрез интеграция с Jetpack, Hilt автоматично управлява контейнерите и жизнените цикли, което ни позволява да се съсредоточим върху бизнес логиката, вместо да местим обекти, сякаш сме при преместване.

Първоначална конфигурация на средата

За да започнете с Hilt, първата стъпка е да подготвите Gradle средата. Важно е да добавите hilt-android-gradle-plugin към конфигурационния файл на ниво проект. След това, в модулния файл на приложението, трябва да приложите плъгина и да добавите съответните зависимости, като се уверите, че компилаторът (независимо дали използва kapt или KSP) е правилно конфигуриран.

Един важен детайл е, че за да работи всичко гладко, проектът трябва да бъде конфигуриран да използва Java 17 (или Java 8 за по-стари версии), тъй като това е предпоставка за безпроблемната съвместна работа на Hilt и Jetpack Compose . Ако забележите, че програмата не се компилира, когато активирате плъгина, проверете отново дали версиите на Kotlin и KSP съвпадат точно, тъй като дори малко несъответствие може да прекъсне целия процес на компилация.

Сърцето на Хилт: Класът за кандидатстване

Всяко приложение, което иска да се възползва от тази библиотека, трябва да има персонализиран клас Application. Само създаването му не е достатъчно; той трябва да бъде маркиран с анотацията @HiltAndroidApp . Този ред задейства генерирането на код от Hilt и създава root контейнера на приложението.

Контекст на Android
Свързана статия:
Пълно ръководство за контекста в Android: Какво е това и как да го управлявате

Този компонент от най-високо ниво е жизненоважен, защото е свързан с цялостния жизнен цикъл на приложението и служи като основа за всички останали компоненти за достъп до зависимостите, дефинирани на това ниво. Разбира се, не забравяйте да регистрирате този клас във файла AndroidManifest.xml, като използвате атрибута name, в противен случай Hilt ще остане напълно незабелязан.

Инжектиране на зависимости в Android компоненти

След като приложението е готово, можем да започнем да инжектираме зависимости в дейности, фрагменти, изгледи или услуги. За да направим това, използваме анотацията @AndroidEntryPoint . Това казва на Hilt, че този клас е входна точка и че трябва да генерира специфичен компонент за него.

Когато искаме да получим специфична зависимост в рамките на дадена дейност, използваме инжектиране на полета чрез анотацията @Inject. Много е важно да запомним, че тези полета не могат да бъдат частни ; ако се опитате да използвате модификатора private, компилаторът ще издаде грешка без колебание. В случая на Jetpack Compose, простото анотиране на коренната дейност ни позволява да осъществяваме достъп до ViewModels директно в рамките на композируемите функции.

Стратегии за определяне на връзките

Hilt трябва да знае как да създаде обектите, които изискваме. Най-прекият начин е чрез инжектиране на конструктор , където поставяме `@Inject` точно преди конструктора на класа. Това позволява на Hilt да анализира параметрите и да определи как да предостави всяка от тези зависимости.

Има обаче случаи, в които нямаме пълен контрол над класа, например когато използваме външни библиотеки като Retrofit или OkHttpClient. Тук се намесват Hilt модулите . Модулът е клас, анотиран с @Module и трябва да включва @InstallIn, за да се посочи кой компонент трябва да съдържа тази зависимост.

  • Използване на @Provides: Това се използва, когато класът е на трета страна или изисква сложен модел на конструкция. Тук дефинираме функция, която връща необходимия екземпляр.
  • Използване на @Binds: Това е идеалният вариант, когато искаме да свържем интерфейс с конкретна имплементация. Дефинира се като абстрактна функция, която казва на Hilt: „когато някой поиска този интерфейс, да му даде тази имплементация.“

Управление на обхвата и жизнения цикъл

По подразбиране Hilt създава нов екземпляр всеки път, когато се изисква зависимост. Понякога обаче е необходимо даден обект да остане същият през целия жизнен цикъл на приложението или екрана. За тази цел използваме обхвати на компоненти.

Ако маркираме клас с @Singleton и го инсталираме в SingletonComponent, ще имаме един глобален екземпляр. Ако предпочитаме обектът да съществува само за времето на действието, използваме @ActivityScoped в ActivityComponent. Изключително важно е да не се прекалява с използването на области на видимост, тъй като твърде дългото задържане на обекти в паметта може да повлияе негативно на производителността на приложението.

Специални случаи и квалификатори

Понякога се налага да инжектираме две различни имплементации на един и същ интерфейс. За да избегнем претоварване на компилатора, използваме квалификатори . Квалификаторът е по същество персонализирана анотация, използвана за етикетиране на специфично обвързване, което ни позволява да разграничим например HTTP клиент за удостоверяване от такъв за общи заявки.

mvvm
Свързана статия:
MVVM: Най-добрият модел на софтуерна архитектура за съвременни приложения

Освен това, Hilt опростява нещата с предварително дефинирани квалификатори като @ApplicationContext и @ActivityContext, което ни позволява да получим контекста на Android, без да се налага ръчно да конфигурираме модули. И накрая, за класове, които Hilt не поддържа нативно (като ContentProviders), можем да използваме анотацията @EntryPoint , създавайки ръчен мост за извличане на зависимости от графиката на Hilt. Споделете тази информация, за да могат повече потребители да научат за нея.


Добавяне като предпочитан източник в Google