Pokud vyvíjíte aplikace pro Android, pravděpodobně jste se setkali s potřebou lépe uspořádat své třídy, abyste zabránili tomu, aby se projekt propadl do naprostého chaosu. A zde přichází na řadu tzv . „dependency injection“ , návrhový vzor, který se sice zpočátku může jevit jako černá magie, ale v podstatě je to způsob, jak každé třídě poskytnout potřebné objekty, aniž by si je musela třída sama vytvářet.
Hilt přichází, aby nás zachránil před složitostí Daggeru a nabízí vrchní vrstvu, která standardizuje vkládání závislostí . Díky integraci s Jetpackem Hilt automaticky spravuje kontejnery a životní cykly, což nám umožňuje soustředit se na obchodní logiku namísto přesouvání objektů, jako bychom se stěhovali.
Počáteční konfigurace prostředí
Abyste mohli začít s Hilt, prvním krokem je příprava prostředí Gradle. Je nezbytné přidat plugin hilt-android-gradle-plugin do konfiguračního souboru na úrovni projektu. Poté je třeba v souboru modulu vaší aplikace použít plugin a přidat odpovídající závislosti a zajistit, aby byl kompilátor (ať už používáte kapt nebo KSP) správně nakonfigurován.
Jedním z klíčových detailů je, že pro hladký chod projektu musí být nakonfigurován pro použití Javy 17 (nebo Javy 8 pro starší verze), protože to je předpoklad pro bezproblémovou spolupráci Hilt a Jetpack Compose . Pokud si všimnete, že se program po aktivaci pluginu nezkompiluje, zkontrolujte, zda se verze Kotlin a KSP přesně shodují, protože i malý rozdíl může narušit celý proces kompilace.
Srdce Hilt: Třída aplikací
Každá aplikace, která chce využívat výhod této knihovny, musí mít vlastní třídu Application. Pouhé její vytvoření nestačí; musí být označena anotací @HiltAndroidApp . Tento řádek spustí generování kódu Hilt a vytvoří kořenový kontejner aplikace.
Tato komponenta nejvyšší úrovně je zásadní, protože se vztahuje k celkovému životnímu cyklu aplikace a slouží jako základ pro všechny ostatní komponenty , aby mohly přistupovat k závislostem definovaným na této úrovni. Samozřejmě nezapomeňte tuto třídu zaregistrovat v souboru AndroidManifest.xml pomocí atributu name, jinak Hilt zůstane zcela bez povšimnutí.
Vkládání závislostí do komponent Androidu
Jakmile je aplikace připravená, můžeme začít vkládat závislosti do aktivit, fragmentů, zobrazení nebo služeb. K tomu použijeme anotaci @AndroidEntryPoint . Ta říká Hilt, že se jedná o vstupní bod a že by pro ni měl vygenerovat specifickou komponentu.
Pokud chceme získat specifickou závislost v rámci aktivity, použijeme vkládání polí pomocí anotace @Inject. Je velmi důležité si uvědomit, že tato pole nemohou být private ; pokud se pokusíte použít modifikátor private, kompilátor bez váhání vyvolá chybu. V případě Jetpack Compose nám pouhá anotace kořenové aktivity umožňuje přístup k ViewModelům přímo v rámci komponovatelných funkcí.
Strategie pro definování vazeb
Hilt potřebuje vědět, jak vytvořit požadované objekty. Nejpřímějším způsobem je vložení konstruktoru , kde umístíme `@Inject` těsně před konstruktor třídy. To umožňuje Hilt analyzovat parametry a určit, jak poskytnout každou z těchto závislostí.
Existují však případy, kdy nemáme nad třídou úplnou kontrolu, například při použití externích knihoven jako Retrofit nebo OkHttpClient. Zde přicházejí na řadu moduly Hilt . Modul je třída anotovaná pomocí @Module a musí obsahovat @InstallIn, který určuje, která komponenta by měla danou závislost obsahovat.
- Použití @Provides: Toto se používá, když je třída od třetí strany nebo vyžaduje složitý konstrukční vzor. Zde definujeme funkci, která vrací potřebnou instanci.
- Použití @Binds: Toto je ideální volba, když chceme propojit rozhraní s konkrétní implementací. Je definována jako abstraktní funkce, která říká Hilt: „Když si někdo vyžádá toto rozhraní, dejte mu tuto implementaci.“
Řízení rozsahu a životního cyklu
Ve výchozím nastavení Hilt vytvoří novou instanci pokaždé, když je vyžádána závislost. Někdy však potřebujeme, aby objekt zůstal stejný po celou dobu existence aplikace nebo obrazovky. K tomu používáme rozsahy komponent.
Pokud označíme třídu pomocí @Singleton a nainstalujeme ji do SingletonComponent, budeme mít jednu globální instanci. Pokud preferujeme, aby objekt existoval pouze po dobu trvání aktivity, použijeme @ActivityScoped v rámci ActivityComponent. Je důležité nepřeužívat obory, protože příliš dlouhé uchovávání objektů v paměti může negativně ovlivnit výkon aplikace.
Zvláštní případy a kvalifikátory
Někdy potřebujeme vložit dvě různé implementace stejného rozhraní. Abychom se vyhnuli zahlcení kompilátoru, používáme kvalifikátory . Kvalifikátor je v podstatě vlastní anotace používaná k označení specifické vazby, která nám umožňuje rozlišit například mezi HTTP klientem pro ověřování a klientem pro obecné požadavky.
Hilt dále zjednodušuje věci pomocí předdefinovaných kvalifikátorů, jako jsou @ApplicationContext a @ActivityContext, což nám umožňuje získat kontext Androidu bez nutnosti ruční konfigurace modulů. A konečně, pro třídy, které Hilt nativně nepodporuje (například ContentProviders), můžeme použít anotaci @EntryPoint , čímž vytvoříme ruční most pro extrakci závislostí z grafu Hilt. Sdílejte tyto informace, aby se o nich mohlo dozvědět více uživatelů.