Ako ste ikada osjećali da kod vaše Android aplikacije postaje potpuni kaos, s instancama koje se prenose iz jedne klase u drugu poput vrućeg krumpira, vjerojatno ste upali u zamku... pakao ovisnostiKako bi spriječio da vaš projekt postane neupravljiv, Google je predstavio Dagger Hilt, alat koji obavlja sav teški posao, automatizirajući isporuku objekata potrebnih vašim klasama bez potrebe da stalno pišete isti kod dok vam ne dosadi.
Za razliku od konvencionalnog Daggera, koji ponekad može biti zastrašujući zbog svoje strme krivulje učenja, Hilt nudi puno standardiziraniji i izravniji pristup. Izvrsno funkcionira s Jetpack Compose i moderne arhitekture, optimizirajući performanse tijekom izvođenja i osiguravajući da ne naiđete na neugodna iznenađenja s nedostajućim greškama ovisnosti, jer se sve validira tijekom kompilacije.
Početna konfiguracija i pokretanje sustava
Za početak korištenja Hilta, prvi korak je postavljanje okruženja u vašim Gradle datotekama. Ključno je dodati hilt-android-gradle-plugin u korijensku datoteku, a zatim primijeniti ovisnosti na vaš aplikacijski modul. Ključna stvar ovdje je da projekt mora biti konfiguriran za Java 17Inače, trenutne verzije Hilta i Composea mogle bi vam zadati dosta glavobolja.
Da bi magija počela djelovati, svaka aplikacija koja želi koristiti ovaj sustav mora imati klasu Application označenu anotacijom @HiltAndroidAppOva oznaka je prekidač koji aktivira generiranje koda i stvara bazu na kojoj će se nalaziti cijeli graf objekta; bez nje, Hilt ne bi imao gdje se usidriti i ništa što radite ne bi radilo.
Ubrizgavanje ovisnosti u Android komponente
Nakon što je baza postavljena, moramo reći Hilt-u u koje klase želimo primiti objekte. Za to koristimo @AndroidEntryPointOvo je kompatibilno s većinom dijelova okvira, kao što su Aktivnosti, Usluge i Prijemnici emitiranja. Ako koristite Compose, jednostavno označite korijensku Aktivnost i svi sastavljivi elementi moći će pristupiti ubrizganim ViewModelima bez ikakvih problema.
Za izravno umetanje objekta u kod aktivnosti koristimo injektiranje polja s @UbrizgatiSamo trebate definirati varijablu kao `lateinit var` i dodati anotaciju. Međutim, budite vrlo oprezni: ubrizgana polja ne mogu biti privatnijer Hilt treba pristup njima za dodjelu instance; ako ih pokušate učiniti privatnima, kompajler će vam odmah dati grešku.
Umjetnost povezivanja: @Binds naspram @Provides
Hilt mora znati kako proizvesti sve što mu zatražimo. Najjednostavniji način je ubrizgavanje konstruktora, gdje konstruktor klase označavamo s `@Inject`. Ali postoje slučajevi kada je to nemoguće, kao na primjer kada se radi s vanjska sučelja ili biblioteke Naknadna ugradnja ili tip sobe, gdje ne možemo dirati izvorni kod za dodavanje napomena.
Tu dolaze do izražaja moduli, klase označene s @Module i @InstallIn. Ako želimo povezati sučelje s konkretnom implementacijom, najučinkovitiji način je korištenje @Veže seDefinirana je apstraktna funkcija gdje je parametar implementacija, a povrat sučelje; u osnovi govori Hilt-u: "kada netko želi AnalyticsService, dajte mu AnalyticsServiceImpl".
S druge strane, kada stvaranje objekta zahtijeva složeniju logiku ili dolazi od treće strane, koristimo @PružaOvdje pišemo normalnu funkciju gdje tijelo detaljno opisuje kako je instanca konstruirana, kao prilikom konfiguriranja osnovnog URL-a Retrofit klijenta. Ukratko, dok se @Binds koristi za delegiranje, @Provides se koristi za ručno stvorite ovisnost.
Upravljanje sukobima pomoću @Qualifiera
Ponekad nam trebaju dvije različite verzije istog tipa objekta. Zamislite da imate dva OkHttpClient klijenta: jedan za pozive koji zahtijevaju autentifikaciju i drugi za javne zahtjeve. Ako pokušamo ubrizgati oba bez daljnje konfiguracije, Hilt će paničariti jer neće znati koji odabrati. Da bismo riješili ovaj problem, koristimo... prilagođeni kvalifikatori.
Kvalifikator je u osnovi samonapomena označena s @KvalifikatorIzrađujemo oznake poput @AuthInterceptorOkHttpClient i postavljamo ih u metodu modula koja pruža instancu i tamo gdje je ubrizgavamo. Na taj način Hilt može razlikovati povezivanja istog tipa bez grešaka. Osim toga, postoje vrlo korisni unaprijed izgrađeni kvalifikatori kao što su @ApplicationContext i @ActivityContextšto nas štedi od stvaranja vlastitih modula za dobivanje Androidov kontekst.
Sinkronizacija životnih ciklusa i opsega
Prema zadanim postavkama, Hilt stvara novu instancu svaki put kada se zatraži ovisnost. Međutim, postoje situacije u kojima želimo da objekt ostane isti tijekom cijelog životnog vijeka komponente. Za to imamo... opsegaAko označimo klasu s @Singleton i instaliramo je u SingletonComponent, imat ćemo jednu instancu dijeljenu kroz cijelu aplikaciju.
Postoje i specifičnije razine. Na primjer, @ActivityScoped `@ViewModelScoped` osigurava da se ista instanca koristi tijekom cijelog životnog vijeka aktivnosti, dok `@ViewModelScoped` radi isto za ViewModel, sprječavajući ponovno stvaranje ovisnosti prilikom rotiranja zaslona. Međutim, nije preporučljivo pretjerano koristiti opsege, jer predugo zadržavanje objekata u memoriji može dovesti do problema. narušiti izvedbu i upravljanje memorijom u Androidu.
Posebni slučajevi: @EntryPoint i nepodržane klase
Hilt je vrlo moćan, ali ne doseže svugdje. Postoje sistemske klase, poput ContentProvider-a, koje ne podržavaju @AndroidEntryPoint. U tim scenarijima rješenje je stvaranje ulazne točke pomoću @UlaznaTočkaOvo definira sučelje koje služi kao most između koda kojim upravlja Hilt i vanjskog koda.
Za oporavak objekata s ovog mosta koristili smo Pristupne točke ulazaProsljeđujemo mu odgovarajući kontekst i EntryPoint sučelje, što nam omogućuje ručno izdvajanje ovisnosti iz Hilt grafa čak i u onim kutovima do kojih automatsko ubrizgavanje ne može doći.
Razlike između balčaka i bodeža
Hilt nije zamjena za Dagger, već je izgrađen na njemu. Njegova glavna prednost je što eliminira potrebu za ručnim pisanjem komponenti i upravljanjem njihovim životnim ciklusima, budući da Automatski generira kontejnere povezano s Android klasama. To drastično smanjuje ponavljajući kod i čini projekt puno čitljivijim.
Ovaj sustav omogućuje da inverzija kontrole bude prirodan proces: klase vam govore što im je potrebno, a Hilt se brine o tome da to osigura. To ne samo da pojednostavljuje svakodnevni razvoj, već je i blagoslov za jedinični testovijer možemo zamijeniti stvarne implementacije s testnim duplima bez diranja poslovne logike.
Implementacija Hilta u Androidu omogućuje robusno i učinkovito upravljanje ovisnostima, eliminirajući redundantni kod i olakšavajući stvaranje skalabilnih aplikacija. Zahvaljujući preciznoj upotrebi @Binds, @Provides i @QualifierRazvojni programeri mogu rješavati sukobe tipova i upravljati životnim ciklusom objekta na granularni način, osiguravajući da je aplikacija održiva i jednostavna za testiranje putem inverzije kontrole.