Wstrzykiwanie zależności za pomocą Hilt

Hilt to biblioteka wstrzykiwania zależności na Androidzie, która zmniejsza ilość kodu szablonowego potrzebnego do 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 poprawności w czasie kompilacji, wydajności w czasie działania, skalowalności i obsługi Androida Studio zapewnianych przez Daggera. Więcej informacji znajdziesz w sekcji Hilt i Dagger.

Z tego przewodnika dowiesz się, czym jest Hilt i jak działają generowane przez niego kontenery. Pokazujemy też, jak uruchomić istniejącą aplikację, aby korzystała z Hilt.

Dodawanie zależności

Najpierw dodaj wtyczkę hilt-android-gradle-plugin do pliku głównego build.gradle 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 mieć pewność, że projekt jest skonfigurowany pod kątem Javy 17, która jest wymagana przez wersje 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 korzystają z Hilt, muszą zawierać klasę Application oznaczoną adnotacją @HiltAndroidApp.

@HiltAndroidApp wywołuje 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 powiązany z obiektem Application i zapewnia mu zależności. Jest to też komponent nadrzędny aplikacji, co oznacza, że inne komponenty mogą uzyskiwać dostęp do zależności, które on udostępnia.

Wstrzykiwanie zależności do klas Androida

Gdy Hilt jest skonfigurowany w klasie Application i dostępny jest komponent 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 (przy użyciu @HiltAndroidApp)
  • ViewModel (przy użyciu @HiltViewModel)
  • Activity
  • Service
  • BroadcastReceiver

W Compose nie musisz dodawać adnotacji do poszczególnych funkcji kompozycyjnych. Zamiast tego dodaj do elementu głównego ComponentActivity adnotację @AndroidEntryPoint. Jest to pojedynczy punkt wejścia DI dla całej hierarchii interfejsu, dzięki czemu możesz uzyskiwać dostęp do wstrzykiwanych przez Hilt obiektów ViewModel bezpośrednio w funkcjach kompozycyjnych.

@AndroidEntryPoint generuje osobny komponent Hilt dla każdej klasy Androida w projekcie. Komponenty te mogą otrzymywać zależności z odpowiednich klas nadrzędnych zgodnie z opisem 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 wstrzykiwane przez Hilt mogą mieć inne klasy bazowe, które również korzystają z wstrzykiwania. Jeśli klasy są abstrakcyjne, nie wymagają adnotacji @AndroidEntryPoint.

Więcej informacji o tym, w którym wywołaniu zwrotnym cyklu życia klasy Androida następuje wstrzykiwanie, znajdziesz w sekcji Okresy istnienia komponentów.

Definiowanie powiązań Hilt

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

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

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

Parametry konstruktora klasy z adnotacjami są zależnościami tej klasy. W tym przykładzie AnalyticsAdapter ma AnalyticsService jako zależność. Dlatego Hilt musi też wiedzieć, jak udostępniać instancje interfejsu AnalyticsService.

Moduły Hilt

Czasami nie można wstrzyknąć typu za pomocą konstruktora. Może to wynikać z wielu powodów. Nie możesz na przykład wstrzykiwać interfejsu za pomocą konstruktora. Nie możesz też wstrzykiwać przez konstruktor typu, którego nie jesteś właścicielem, np. klasy z biblioteki zewnętrznej. W takich przypadkach możesz przekazać Hiltowi informacje o powiązaniach za pomocą modułów Hilta.

Moduł Hilt to klasa oznaczona adnotacją @Module. Zawiera instrukcje dla Hilta dotyczące tworzenia instancji typów, których nie można udostępnić za pomocą wstrzykiwania przez konstruktor, takich jak interfejsy lub klasy zewnętrzne. Musisz też oznaczyć każdy moduł adnotacją @InstallIn, aby poinformować Hilt, w której klasie Androida będzie używany lub instalowany dany moduł.

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

Wstrzykiwanie instancji interfejsów za pomocą adnotacji @Binds

Zapoznaj się z przykładem AnalyticsService. Jeśli AnalyticsService jest interfejsem, nie możesz go wstrzyknąć za pomocą konstruktora. Zamiast tego przekaż Hiltowi informacje o powiązaniu, tworząc w module Hilt funkcję abstrakcyjną z adnotacją @Binds.

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

Funkcja z adnotacjami przekazuje do Hilt te informacje:

  • Zwracany typ funkcji informuje Hilt, jakiego interfejsu dostarcza 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 wstrzykiwał 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ą adnotacji @Provides

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

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

Funkcja z adnotacjami dostarcza Hiltowi tych informacji:

  • Zwracany typ funkcji informuje Hilt, jakiego typu instancje udostępnia funkcja.
  • Parametry funkcji informują Hilt o zależnościach odpowiedniego typu.
  • Ciało funkcji informuje Hilta, 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ń tego samego typu

Jeśli chcesz, aby Hilt udostępniał różne implementacje tego samego typu jako zależności, musisz podać Hiltowi wiele powiązań. Możesz zdefiniować wiele powiązań tego samego typu za pomocą kwalifikatorów.

Kwalifikator to adnotacja, której używasz do identyfikowania konkretnego powiązania z typem, gdy typ ma zdefiniowanych wiele powiązań.

Przyjrzyjmy się przykładowi. Jeśli chcesz przechwytywać wywołania funkcji AnalyticsService, możesz użyć obiektu OkHttpClientinterceptor. W przypadku innych usług może być konieczne przechwytywanie połączeń w inny sposób. W takim przypadku musisz poinformować Hilta, jak udostępniać 2 różne implementacje interfejsu OkHttpClient.

Najpierw określ kwalifikatory, których będziesz używać do adnotacji metod @Binds lub @Provides:

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

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

Następnie Hilt musi wiedzieć, jak udostępnić instancję typu, która 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, dodając do pola lub parametru odpowiedni kwalifikator:

// 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 dostarczania tej zależności. Pozostawienie podstawowej lub wspólnej implementacji bez kwalifikatora jest podatne na błędy i może spowodować wstrzyknięcie przez Hilt nieprawidłowej zależności.

Wstępnie zdefiniowane kwalifikatory w Hilt

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

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

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

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

Wygenerowane komponenty klas Androida

Każda klasa Androida, w której możesz przeprowadzić wstrzykiwanie przez pola, ma powiązany komponent Hilt, do którego możesz się odwołać w adnotacji @InstallIn. Każdy komponent Hilt jest odpowiedzialny za wstrzykiwanie powiązań do odpowiedniej klasy Androida.

W poprzednich przykładach pokazaliśmy użycie ActivityComponent w modułach Hilt.

Hilt udostępnia te komponenty:

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

Okresy eksploatacji komponentów

Hilt automatycznie tworzy i usuwa instancje wygenerowanych klas komponentów, śledząc cykl życia odpowiednich klas Androida.

Wygenerowany komponent Utworzono o Zniszczono o
SingletonComponent Application#onCreate() Application zniszczony
ActivityRetainedComponent Activity#onCreate() Activity#onDestroy()
ViewModelComponent Utworzono: ViewModel ViewModel zniszczony
ActivityComponent Activity#onCreate() Activity#onDestroy()
ServiceComponent Service#onCreate() Service#onDestroy()

Zakresy komponentów

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

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

Hilt umożliwia jednak też ograniczenie zakresu powiązania do określonego komponentu. Hilt tworzy powiązanie w zakresie tylko raz na instancję komponentu, do którego zakresu należy powiązanie, a wszystkie żądania tego powiązania korzystają z tej samej instancji.

W tabeli poniżej znajdziesz adnotacje dotyczące zakresu poszczególnych wygenerowanych komponentów:

Zajęcia w Classroomie Wygenerowany komponent Zakres
Application SingletonComponent @Singleton
Activity ActivityRetainedComponent @ActivityRetainedScoped
ViewModel ViewModelComponent @ViewModelScoped
Activity ActivityComponent @ActivityScoped
Service ServiceComponent @ServiceScoped

W tym przykładzie, jeśli ograniczysz zakres AnalyticsAdapter do ActivityComponent za pomocą @ActivityScoped, Hilt będzie udostępniać tę samą instancję AnalyticsAdapter przez cały okres istnienia 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 odpowiednie jest ograniczenie zakresu AnalyticsService do SingletonComponent. Dzięki temu za każdym razem, gdy komponent musi udostępnić instancję AnalyticsService, udostępnia 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 ono zainstalowane. W tym przykładzie musisz zainstalować AnalyticsServiceSingletonComponent 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 w hierarchii komponentów.

Komponent aktywności jest podrzędny względem komponentu zachowywanego aktywności. ViewModelComponent jest podrzędnym komponentem ActivityRetainedComponent. ActivityRetainedComponent i ServiceComponent
    należą do SingletonComponent.
Rysunek 1. Hierarchia komponentów generowanych przez Hilt.

Domyślne powiązania komponentów

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 żadnej konkretnej podklasie. Wynika to z faktu, że 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

Powią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 { ... }

Powią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() w funkcji kompozycyjnej w celu uzyskania dostępu do ViewModel. Hilt obsługuje większość najpopularniejszych klas Androida, ale 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 przez niego zarządzany. 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 Hilt nie zarządza, do udostępniania zależności w grafie zależności.

Na przykład Hilt nie obsługuje bezpośrednio dostawców treści. Jeśli chcesz, aby dostawca treści używał Hilta do pobierania niektórych zależności, musisz zdefiniować interfejs z adnotacją @EntryPoint dla każdego typu powiązania, którego chcesz użyć, i uwzględnić kwalifikatory. Następnie dodaj @InstallIn, aby określić komponent, w którym ma zostać zainstalowany punkt wejścia:

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 klasy EntryPointAccessors. Parametr powinien być instancją komponentu lub obiektem @AndroidEntryPoint, który pełni rolę kontenera komponentu. Upewnij się, że komponent przekazywany jako parametr i statyczna metoda EntryPointAccessors są zgodne z klasą 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 and Dagger

Hilt to oficjalnie rekomendowana biblioteka do wstrzykiwania zależności na Androidzie. Zapewnia on standardowy, oparty na opiniach i wydajny sposób implementowania wstrzykiwania zależności w aplikacji, który jest zoptymalizowany pod kątem Jetpack Compose i architektur z jednym działaniem.

Cele Hilt:

  • Aby utworzyć standardowy zestaw komponentów i zakresów, który ułatwi konfigurację, czytelność i udostępnianie kodu między aplikacjami.
  • Aby zapewnić łatwy sposób udostępniania różnych powiązań różnym typom kompilacji, takim jak testowa, debugowania czy produkcyjna.

System operacyjny Android tworzy instancje wielu własnych klas frameworka, więc używanie Daggera w aplikacji na Androida wymaga napisania znacznej ilości kodu szablonowego. Hilt ogranicza liczbę powtarzalnych fragmentów kodu związanych z używaniem Daggera w aplikacji na Androida. Hilt automatycznie generuje i udostępnia te elementy:

  • Komponenty do integrowania klas platformy Android z Daggerem, które w inny sposób musiał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@ActivityContext.

Kod Daggera i Hilta może współistnieć w tej samej bazie kodu. W większości przypadków najlepiej jest jednak używać Hilta do zarządzania wszystkimi przypadkami użycia Daggera na Androidzie. Jeśli chcesz przenieść projekt, który korzysta z Daggera, 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