Wstrzykiwanie zależności za pomocą Hilt

Hilt to biblioteka wstrzykiwania zależności na Androida, która zmniejsza ilość powtarzalnego kodu podczas ręcznego wstrzykiwania zależności w projekcie. Ręczne wstrzykiwanie zależności wymaga ręcznego tworzenia każdej klasy i jej zależności oraz używania kontenerów do ponownego wykorzystywania zależności i zarządzania nimi.

Hilt zapewnia standardowy sposób korzystania z DI w aplikacji, udostępniając kontenery dla każdej klasy Androida w projekcie i automatycznie zarządzając ich cyklami życia. Hilt jest oparty na popularnej bibliotece DI Dagger, dzięki czemu korzysta z zapewnianej przez nią poprawności w czasie kompilowania, wydajności w czasie działania, skalowalności i obsługi Android Studio. Więcej informacji znajdziesz w sekcji Hilt i Dagger.

W tym przewodniku wyjaśniamy podstawowe pojęcia związane z Hilt i wygenerowanymi przez niego kontenerami. Zawiera też demonstrację, jak uruchomić istniejącą aplikację, aby korzystała z Hilt.

Dodawanie zależności

Najpierw dodaj wtyczkę hilt-android-gradle-plugin do pliku build.gradle w katalogu głównym projektu:

Kotlin

plugins {
  ...
  id("com.google.dagger.hilt.android") version "2.57.1" apply false
}

Dynamiczny

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

Następnie zastosuj wtyczkę Gradle i dodaj te zależności w pliku app/build.gradle:

Kotlin

plugins {
  id("com.google.devtools.ksp")
  id("com.google.dagger.hilt.android")
}

android {
  ...
}

dependencies {
  implementation("com.google.dagger:hilt-android:2.57.1")
  ksp("com.google.dagger:hilt-android-compiler:2.57.1")
}

Dynamiczny

...
plugins {
  id 'com.google.devtools.ksp'
  id 'com.google.dagger.hilt.android'
}

android {
  ...
}

dependencies {
  implementation "com.google.dagger:hilt-android:2.57.1"
  ksp "com.google.dagger:hilt-compiler:2.57.1"
}

Aby upewnić się, że projekt jest skonfigurowany pod kątem Javy 17, która jest wymagana przez Jetpack Compose i Hilt, dodaj do pliku app/build.gradle te informacje:

Kotlin

android {
  ...
  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
  }
}

Dynamiczny

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

Klasa aplikacji Hilt

Wszystkie aplikacje, które używają Hilt, muszą zawierać klasę Application oznaczoną adnotacją @HiltAndroidApp.

@HiltAndroidApp aktywuje generowanie kodu Hilt, w tym klasy bazowej aplikacji, która służy jako kontener zależności na poziomie aplikacji.

@HiltAndroidApp
class ExampleApplication : Application() { ... }

Ten wygenerowany komponent Hilt jest dołączony do cyklu życia obiektu Application i zapewnia mu zależności. Jest to również komponent nadrzędny aplikacji, co oznacza, że inne komponenty mogą uzyskiwać dostęp do zależności, które udostępnia.

Wstrzykiwanie zależności do klas Androida

Po skonfigurowaniu Hilt w klasie Application i udostępnieniu komponentu na poziomie aplikacji Hilt może dostarczać zależności do innych klas Androida, które mają adnotację @AndroidEntryPoint:

@AndroidEntryPoint
class ExampleActivity : ComponentActivity() { ... }

Hilt obsługuje obecnie te klasy Androida:

  • Application (za pomocą @HiltAndroidApp)
  • ViewModel (za pomocą @HiltViewModel)
  • Activity
  • Service
  • BroadcastReceiver

W Compose nie musisz dodawać adnotacji do poszczególnych funkcji kompozycyjnych. Zamiast tego dodaj do głównego elementu ComponentActivity adnotację @AndroidEntryPoint. Służy jako pojedynczy punkt wejścia DI dla całej hierarchii interfejsu, dzięki czemu możesz uzyskiwać dostęp do modeli widoku wstrzykiwanych przez Hilt bezpośrednio w funkcjach typu „composable”.

@AndroidEntryPoint generuje osobny komponent Hilt dla każdej klasy Androida w projekcie. Te komponenty mogą otrzymywać zależności od odpowiednich klas nadrzędnych, jak opisano w sekcji Hierarchia komponentów.

Aby uzyskać zależności z komponentu, użyj adnotacji @Inject do wstrzykiwania przez pola:

@AndroidEntryPoint
class ExampleActivity : ComponentActivity() {

  @Inject lateinit var analytics: AnalyticsAdapter
  ...
}

Klasy, które wstrzykuje Hilt, mogą mieć inne klasy bazowe, które również używają wstrzykiwania. Te klasy nie potrzebują adnotacji @AndroidEntryPoint, jeśli są abstrakcyjne.

Więcej informacji o tym, do którego wywołania zwrotnego cyklu życia jest wstrzykiwana klasa Androida, znajdziesz w artykule o czasie życia komponentu.

Definiowanie powiązań Hilt

Aby przeprowadzić wstrzykiwanie przez pola, Hilt musi wiedzieć, jak dostarczyć instancje niezbędnych zależności z odpowiedniego komponentu. Wiązanie zawiera informacje niezbędne do udostępniania instancji typu jako zależności.

Jednym ze sposobów przekazywania informacji o powiązaniach do Hilt jest wstrzykiwanie przez konstruktor. Użyj adnotacji @Inject w konstruktorze klasy, aby poinformować Hilt, jak dostarczać instancje tej klasy:

class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

Parametry konstruktora klasy z adnotacją są zależnościami tej klasy. W tym przykładzie AnalyticsAdapter ma zależność AnalyticsService. Dlatego Hilt musi też wiedzieć, jak dostarczać instancje klasy AnalyticsService.

Moduły Hilt

Czasami nie można wstrzyknąć typu przez konstruktor. Może się to zdarzyć z kilku powodów. Nie można na przykład wstrzyknąć interfejsu przez konstruktor. Nie można też wstrzykiwać przez konstruktor typu, który nie należy do Ciebie, np. klasy z biblioteki zewnętrznej. W takich przypadkach możesz przekazać Hilt informacje o powiązaniach za pomocą modułów Hilt.

Moduł Hilt to klasa z adnotacją @Module. Dostarcza on Hiltowi instrukcje tworzenia instancji typów, których nie można dostarczyć przez wstrzykiwanie przez konstruktor, takich jak interfejsy czy klasy innych firm. Musisz też dodać do każdego modułu adnotację @InstallIn, aby poinformować Hilt, w której klasie Androida będzie używany lub instalowany dany moduł.

Zależności, które podajesz w modułach Hilt, są dostępne we wszystkich wygenerowanych komponentach powiązanych z klasą Androida, w której instalujesz moduł Hilt.

Wstrzykiwanie instancji interfejsu za pomocą @Binds

Rozważmy przykład AnalyticsService. Jeśli AnalyticsService jest interfejsem, nie można go wstrzyknąć przez konstruktor. Zamiast tego podaj Hiltowi informacje o powiązaniu, tworząc funkcję abstrakcyjną z adnotacją @Binds w module Hilt.

Adnotacja @Binds informuje Hilt, której implementacji ma użyć, gdy musi dostarczyć instancję interfejsu.

Funkcja z adnotacją dostarcza do Hilt te informacje:

  • Zwracany typ funkcji informuje Hilt, dla jakiego interfejsu funkcja udostępnia instancje.
  • Parametr funkcji informuje Hilt, którą implementację ma udostępnić.
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
}

Moduł Hilt AnalyticsModule jest oznaczony adnotacją @InstallIn(ActivityComponent.class), ponieważ chcesz, aby Hilt wstrzyknął tę zależność do ExampleActivity. Ta adnotacja oznacza, że wszystkie zależności w AnalyticsModule są dostępne we wszystkich aktywnościach aplikacji.

Wstrzykiwanie instancji za pomocą @Provides

Interfejsy nie są jedynym przypadkiem, w którym nie można wstrzyknąć typu przez konstruktor. Wstrzykiwanie przez konstruktor nie jest też możliwe, jeśli nie jesteś właścicielem klasy, ponieważ pochodzi ona z biblioteki zewnętrznej (klasy takie jak Retrofit, OkHttpClient lub bazy danych Room), lub jeśli instancje muszą być tworzone za pomocą wzorca budowniczego.

Rozważmy poprzedni przykład. Jeśli nie jesteś bezpośrednim właścicielem klasy AnalyticsService, możesz poinformować Hilt, jak dostarczać instancje tego typu, tworząc funkcję w module Hilt i dodając do niej adnotację @Provides.

Funkcja z adnotacją dostarcza do Hilt te informacje:

  • Zwracany typ funkcji informuje Hilt, jakiego typu instancje udostępnia funkcja.
  • Parametry funkcji informują Hilt o zależnościach odpowiedniego typu.
  • Treść funkcji informuje Hilt, jak dostarczyć instancję odpowiedniego typu. Hilt wykonuje treść funkcji za każdym razem, gdy musi dostarczyć instancję tego typu.
@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)
  }
}

Podawanie wielu powiązań dla tego samego typu

W przypadkach, gdy Hilt ma dostarczać różne implementacje tego samego typu jako zależności, musisz podać wiele powiązań. Możesz zdefiniować wiele powiązań dla tego samego typu za pomocą kwalifikatorów.

Kwalifikator to adnotacja, której używasz do identyfikacji konkretnego powiązania typu, gdy ten typ ma zdefiniowanych wiele powiązań.

Przeanalizujmy przykład. Jeśli chcesz przechwytywać wywołania do AnalyticsService, możesz użyć obiektu OkHttpClient z interceptorem. W przypadku innych usług może być konieczne przechwytywanie wywołań w inny sposób. W takim przypadku musisz poinformować Hilt, jak udostępnić 2 różne implementacje interfejsu OkHttpClient.

Najpierw zdefiniuj kwalifikatory, których użyjesz do dodawania adnotacji do metod @Binds lub @Provides:

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherInterceptorOkHttpClient

Następnie Hilt musi wiedzieć, jak dostarczyć instancję typu, który odpowiada każdemu kwalifikatorowi. W takim przypadku możesz użyć modułu Hilt z adnotacją @Provides. Obie metody mają ten sam zwracany typ, ale kwalifikatory oznaczają je jako 2 różne powiązania:

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

  @AuthInterceptorOkHttpClient
  @Provides
  fun provideAuthInterceptorOkHttpClient(
    authInterceptor: AuthInterceptor
  ): OkHttpClient {
      return OkHttpClient.Builder()
               .addInterceptor(authInterceptor)
               .build()
  }

  @OtherInterceptorOkHttpClient
  @Provides
  fun provideOtherInterceptorOkHttpClient(
    otherInterceptor: OtherInterceptor
  ): OkHttpClient {
      return OkHttpClient.Builder()
               .addInterceptor(otherInterceptor)
               .build()
  }
}

Możesz wstrzyknąć konkretny typ, którego potrzebujesz, dodając do pola lub parametru adnotację z odpowiednim kwalifikatorem:

// As a dependency of another class.
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {

  @Provides
  fun provideAnalyticsService(
    @AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
  ): AnalyticsService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .client(okHttpClient)
               .build()
               .create(AnalyticsService::class.java)
  }
}

// As a dependency of a constructor-injected class.
class ExampleServiceImpl @Inject constructor(
  @AuthInterceptorOkHttpClient private val okHttpClient: OkHttpClient
) : ...

// At field injection.
@AndroidEntryPoint
class ExampleActivity: ComponentActivity() {

  @AuthInterceptorOkHttpClient
  @Inject lateinit var okHttpClient: OkHttpClient
}

Zgodnie ze sprawdzoną metodą, jeśli dodasz kwalifikator do typu, dodaj kwalifikatory do wszystkich możliwych sposobów zapewnienia tej zależności. Pozostawienie podstawowej lub wspólnej implementacji bez kwalifikatora może prowadzić do błędów i spowodować, że Hilt wstrzyknie nieprawidłową zależność.

Wstępnie zdefiniowane kwalifikatory w Hilt

Hilt udostępnia kilka wstępnie zdefiniowanych kwalifikatorów. Na przykład, ponieważ możesz potrzebować klasy Context z aplikacji lub aktywności, Hilt udostępnia kwalifikatory @ApplicationContext i @ActivityContext.

Załóżmy, że klasa AnalyticsAdapter z przykładu potrzebuje kontekstu aktywności. Poniższy kod pokazuje, jak przekazać kontekst aktywności do AnalyticsAdapter:

class AnalyticsAdapter @Inject constructor(
    @ActivityContext private val context: Context,
    private val service: AnalyticsService
) { ... }

Inne wstępnie zdefiniowane powiązania dostępne w Hilt znajdziesz w sekcji Domyślne powiązania komponentów.

Wygenerowane komponenty klas Androida

Dla każdej klasy Androida, w której można wykonać wstrzykiwanie przez pola, istnieje powiązany komponent Hilt, do którego można się odwołać w adnotacji @InstallIn. Każdy komponent Hilt odpowiada za wstrzykiwanie swoich powiązań do odpowiedniej klasy Androida.

Poprzednie przykłady pokazywały użycie ActivityComponent w modułach Hilt.

Hilt udostępnia te komponenty:

Komponent Hilt Wstrzykiwacz do
SingletonComponent Application
ActivityRetainedComponent Nie dotyczy
ViewModelComponent ViewModel
ActivityComponent Activity
ServiceComponent Service

Czas życia komponentów

Hilt automatycznie tworzy i niszczy instancje wygenerowanych klas komponentów zgodnie z cyklem życia odpowiednich klas Androida.

Wygenerowany komponent Utworzono o Czas zniszczenia
SingletonComponent Application#onCreate() Application zniszczona
ActivityRetainedComponent Activity#onCreate() Activity#onDestroy()
ViewModelComponent Utworzono: ViewModel ViewModel zniszczona
ActivityComponent Activity#onCreate() Activity#onDestroy()
ServiceComponent Service#onCreate() Service#onDestroy()

Zakresy komponentów

Domyślnie wszystkie powiązania w Hilt są bez zakresu. Oznacza to, że za każdym razem, gdy aplikacja żąda powiązania, Hilt tworzy nową instancję wymaganego typu.

W tym przykładzie za każdym razem, gdy Hilt dostarcza AnalyticsAdapter jako zależność do innego typu lub przez wstrzykiwanie przez pola (jak w ExampleActivity), Hilt dostarcza nową instancję AnalyticsAdapter.

Hilt umożliwia jednak również powiązanie z określonym komponentem. Hilt tworzy powiązanie o określonym zakresie tylko raz na instancję komponentu, do którego jest ono przypisane, a wszystkie żądania dotyczące tego powiązania korzystają z tej samej instancji.

W tabeli poniżej znajdziesz adnotacje dotyczące zakresu dla każdego wygenerowanego komponentu:

Klasa Androida Wygenerowany komponent Zakres
Application SingletonComponent @Singleton
Activity ActivityRetainedComponent @ActivityRetainedScoped
ViewModel ViewModelComponent @ViewModelScoped
Activity ActivityComponent @ActivityScoped
Service ServiceComponent @ServiceScoped

Jeśli w tym przykładzie ograniczysz zakres AnalyticsAdapter do ActivityComponent za pomocą @ActivityScoped, Hilt będzie udostępniać tę samą instancję AnalyticsAdapter przez cały czas trwania odpowiedniej aktywności:

@ActivityScoped
class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

Załóżmy, że AnalyticsService ma stan wewnętrzny, który wymaga używania tej samej instancji za każdym razem – nie tylko w ExampleActivity, ale w dowolnym miejscu w aplikacji. W takim przypadku należy ograniczyć zakres AnalyticsService do SingletonComponent. W rezultacie za każdym razem, gdy komponent musi dostarczyć instancję AnalyticsService, dostarcza tę samą instancję.

Poniższy przykład pokazuje, jak ograniczyć zakres powiązania do komponentu w module Hilt. Zakres powiązania musi być zgodny z zakresem komponentu, w którym jest zainstalowany, więc w tym przykładzie musisz zainstalować AnalyticsService w SingletonComponent zamiast w ActivityComponent:

// If AnalyticsService is an interface.
@Module
@InstallIn(SingletonComponent::class)
abstract class AnalyticsModule {

  @Singleton
  @Binds
  abstract fun bindAnalyticsService(
    analyticsServiceImpl: AnalyticsServiceImpl
  ): AnalyticsService
}

// If you don't own AnalyticsService.
@Module
@InstallIn(SingletonComponent::class)
object AnalyticsModule {

  @Singleton
  @Provides
  fun provideAnalyticsService(): AnalyticsService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .build()
               .create(AnalyticsService::class.java)
  }
}

Więcej informacji o zakresach komponentów Hilt znajdziesz w artykule Zakresy w Androidzie i Hilt.

Hierarchia komponentów

Zainstalowanie modułu w komponencie umożliwia dostęp do jego powiązań jako zależności innych powiązań w tym komponencie lub w dowolnym komponencie podrzędnym poniżej w hierarchii komponentów.

ActivityComponent znajduje się pod ActivityRetainedComponent. ViewModelComponent znajduje się pod ActivityRetainedComponent. ActivityRetainedComponent i ServiceComponent znajdują się w SingletonComponent.
Rysunek 1. Hierarchia komponentów generowanych przez Hilt.

Domyślne powiązania komponentu

Każdy komponent Hilt zawiera zestaw domyślnych powiązań, które Hilt może wstrzykiwać jako zależności do Twoich niestandardowych powiązań. Pamiętaj, że te powiązania odpowiadają ogólnemu typowi aktywności, a nie konkretnej podklasie. Dzieje się tak, ponieważ Hilt używa jednej definicji komponentu aktywności do wstrzykiwania wszystkich aktywności. Każda aktywność ma inną instancję tego komponentu.

Komponent Androida Domyślne powiązania
SingletonComponent Application
ActivityRetainedComponent Application
ViewModelComponent SavedStateHandle
ActivityComponent Application, Activity
ServiceComponent Application, Service

Wiązanie kontekstu aplikacji jest też dostępne za pomocą @ApplicationContext. Przykład:

class AnalyticsServiceImpl @Inject constructor(
  @ApplicationContext context: Context
) : AnalyticsService { ... }

// The Application binding is available without qualifiers.
class AnalyticsServiceImpl @Inject constructor(
  application: Application
) : AnalyticsService { ... }

Wiązanie kontekstu aktywności jest też dostępne za pomocą @ActivityContext. Przykład:

class AnalyticsAdapter @Inject constructor(
  @ActivityContext context: Context
) { ... }

// The Activity binding is available without qualifiers.
class AnalyticsAdapter @Inject constructor(
  activity: ComponentActivity
) { ... }

Wstrzykiwanie zależności w klasach nieobsługiwanych przez Hilt

W Compose standardowym wzorcem jest wstrzykiwanie zależności do @HiltViewModel za pomocą wstrzykiwania przez konstruktor, a następnie używanie hiltViewModel() wewnątrz funkcji kompozycyjnej, aby uzyskać dostęp do ViewModel. Chociaż Hilt obsługuje najpopularniejsze klasy Androida, możesz napotkać nieobsługiwane klasy, w których musisz przeprowadzić wstrzykiwanie przez pola.

W takich przypadkach możesz utworzyć punkt wejścia za pomocą adnotacji @EntryPoint. Punkt wejścia to granica między kodem zarządzanym przez Hilt a kodem, który nie jest zarządzany przez tę bibliotekę. Jest to punkt, w którym kod po raz pierwszy wchodzi do grafu obiektów zarządzanych przez Hilt. Punkty wejścia umożliwiają Hiltowi używanie kodu, którym nie zarządza, do dostarczania zależności w grafie zależności.

Na przykład Hilt nie obsługuje bezpośrednio mechanizmów dostarczania treści. Jeśli chcesz, aby mechanizm dostarczania treści używał Hilt do uzyskiwania niektórych zależności, musisz zdefiniować interfejs z adnotacją @EntryPoint dla każdego typu wiązania i uwzględnić kwalifikatory. Następnie dodaj @InstallIn, aby określić komponent, w którym chcesz zainstalować punkt wejścia, w ten sposób:

class ExampleContentProvider : ContentProvider() {

  @EntryPoint
  @InstallIn(SingletonComponent::class)
  interface ExampleContentProviderEntryPoint {
    fun analyticsService(): AnalyticsService
  }

  ...
}

Aby uzyskać dostęp do punktu wejścia, użyj odpowiedniej metody statycznej z EntryPointAccessors. Parametr powinien być instancją komponentu lub obiektem @AndroidEntryPoint, który działa jako obiekt przechowujący komponent. Upewnij się, że komponent przekazywany jako parametr i metoda statyczna EntryPointAccessors pasują do klasy Androida w adnotacji @InstallIn w interfejsie @EntryPoint:

class ExampleContentProvider: ContentProvider() {
    ...

  override fun query(...): Cursor {
    val appContext = context?.applicationContext ?: throw IllegalStateException()
    val hiltEntryPoint =
      EntryPointAccessors.fromApplication(appContext, ExampleContentProviderEntryPoint::class.java)

    val analyticsService = hiltEntryPoint.analyticsService()
    ...
  }
}

W tym przykładzie musisz użyć ApplicationContext, aby pobrać punkt wejścia, ponieważ jest on zainstalowany w SingletonComponent. Jeśli powiązanie, które chcesz pobrać, znajduje się w ActivityComponent, użyj ActivityContext.

Hilt i Dagger

Hilt to oficjalnie zalecana biblioteka do wstrzykiwania zależności na Androidzie. Zapewnia on ustandaryzowany, ugruntowany i wydajny sposób implementacji wstrzykiwania zależności w aplikacji, zoptymalizowany pod kątem Jetpack Compose i architektur z jedną aktywnością.

Cele Hilt:

  • Aby utworzyć standardowy zestaw komponentów i zakresów, który ułatwi konfigurację, czytelność i udostępnianie kodu między aplikacjami.
  • zapewnienie łatwego sposobu udostępniania różnych powiązań różnym typom kompilacji, np. testowym, debugowania lub wersji.

System operacyjny Android tworzy instancje wielu własnych klas platformy, dlatego używanie Daggera w aplikacji na Androida wymaga napisania dużej ilości powtarzalnego kodu. Hilt ogranicza powtarzalny kod, który jest związany z używaniem Daggera w aplikacji na Androida. Hilt automatycznie generuje i udostępnia te elementy:

  • Komponenty do integracji klas platformy Androida z Daggerem, które w przeciwnym razie trzeba by utworzyć ręcznie.
  • Adnotacje dotyczące zakresu do użycia z komponentami, które Hilt generuje automatycznie.
  • Wstępnie zdefiniowane powiązania reprezentujące klasy Androida, takie jak Application lub Activity.
  • Wstępnie zdefiniowane kwalifikatory reprezentujące @ApplicationContext i @ActivityContext.

Kod Dagger i Hilt może współistnieć w tej samej bazie kodu. Jednak w większości przypadków najlepiej jest używać Hilt do zarządzania wszystkimi zastosowaniami Daggera na Androidzie. Aby przenieść projekt, który używa Dagger, do Hilt, zapoznaj się z przewodnikiem po migracji.

Dodatkowe materiały

Więcej informacji o Hilt znajdziesz w tych materiałach.

Przykłady

Blogi

Wyświetlanie treści