Hilt ile bağımlı yerleştirme

Hilt, Android'de kullanıma sunulan ve projenizde manuel bağımlılık yerleştirme işlemi yapma konusunda genel standartları azaltan bir bağımlılık yerleştirme kitaplığıdır. Manuel bağımlılık yerleştirme işlemi yapmak için her sınıfı ve bağımlılıklarını el ile oluşturmanız ve bağımlılıkları yeniden kullanmak ve yönetmek için container'ları kullanmanız gerekir.

Hilt, projenizdeki her Android sınıfı için container'lar sağlayarak ve bunların yaşam döngülerini otomatik olarak yöneterek uygulamanızda DI kullanımının standart bir yolunu sunar. Hilt, Dagger'ın sağladığı derleme zamanı doğruluğu, çalışma zamanı performansı, ölçeklenebilirlik ve Android Studio desteğinden yararlanmak için popüler Dagger DI kitaplığının üzerine inşa edilmiştir. Daha fazla bilgi için Hilt andDagger konusuna bakın.

Bu kılavuzda, Hilt ile oluşturulan container'lar ile ilgili temel kavramlar açıklanmaktadır. Ayrıca, Hilt'in kullanılması için mevcut bir uygulamanın nasıl önyükleneceğine dair bir tanıtım da içermektedir.

Bağımlılık ekleme

İlk olarak, hilt-android-gradle-plugin eklentisini projenizin kök build.gradle dosyasına ekleyin:

Modern

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

Kotlin

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

Ardından Gradle eklentisini uygulayın ve şu bağımlılıkları app/build.gradle dosyanıza ekleyin:

Modern

...
plugins {
  id 'kotlin-kapt'
  id 'com.google.dagger.hilt.android'
}

android {
  ...
}

dependencies {
  implementation "com.google.dagger:hilt-android:2.44"
  kapt "com.google.dagger:hilt-compiler:2.44"
}

// Allow references to generated code
kapt {
  correctErrorTypes true
}

Kotlin

plugins {
  kotlin("kapt")
  id("com.google.dagger.hilt.android")
}

android {
  ...
}

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

// Allow references to generated code
kapt {
  correctErrorTypes = true
}

Hilt, Java 8 özelliklerini kullanır. Projenizde Java 8'i etkinleştirmek için app/build.gradle dosyasına aşağıdaki kodu ekleyin:

Modern

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

Kotlin

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

Hilt uygulama sınıfı

Hilt kullanan tüm uygulamalar, @HiltAndroidApp ek açıklamasına sahip bir Application sınıfı içermelidir.

@HiltAndroidApp, uygulama düzeyinde bağımlılık kapsayıcısı işlevi gören bir temel sınıf da dahil olmak üzere Hilt'in kod oluşturma işlemini tetikler.

Kotlin

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

Java

@HiltAndroidApp
public class ExampleApplication extends Application { ... }

Oluşturulan bu Hilt bileşeni, Application nesnesinin yaşam döngüsüne eklenir ve nesneye bağımlılıklar sağlar. Ayrıca, uygulamanın üst bileşenidir. Diğer bir ifadeyle, diğer bileşenler, sağladığı bağımlılıklara erişebilir.

Android sınıflarına bağımlılık ekleme

Hilt, Application sınıfınızda ayarlandıktan ve uygulama düzeyinde bir bileşen mevcut olduğunda Hilt, @AndroidEntryPoint ek açıklamasına sahip diğer Android sınıflarına bağımlılıklar sağlayabilir:

Kotlin

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

Java

@AndroidEntryPoint
public class ExampleActivity extends AppCompatActivity { ... }

Hilt şu anda aşağıdaki Android sınıflarını desteklemektedir:

  • Application (@HiltAndroidApp kullanarak)
  • ViewModel (@HiltViewModel kullanarak)
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver

Bir Android sınıfına @AndroidEntryPoint ifadesiyle ek açıklama eklerseniz bu sınıfı kullanan Android sınıflarına da ek açıklama girmeniz gerekir. Örneğin, bir parçaya ek açıklama eklerseniz bu parçayı kullandığınız tüm etkinliklere de ek açıklama eklemeniz gerekir.

@AndroidEntryPoint, projenizdeki her Android sınıfı için ayrı bir Hilt bileşeni oluşturur. Bu bileşenler, Bileşen hiyerarşisi bölümünde açıklandığı gibi ilgili üst sınıflarından bağımlılıklar alabilir.

Bir bileşenden bağımlılık elde etmek için alan yerleştirme işlemi gerçekleştirmek üzere @Inject ek açıklamasını kullanın:

Kotlin

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {

  @Inject lateinit var analytics: AnalyticsAdapter
  ...
}

Java

@AndroidEntryPoint
public class ExampleActivity extends AppCompatActivity {

  @Inject
  AnalyticsAdapter analytics;
  ...
}

Hilt'in eklediği sınıfların, yerleştirme kullanan başka temel sınıfları da olabilir. Bu sınıflar soyut olmaları durumunda @AndroidEntryPoint ek açıklamasına ihtiyaç duymaz.

Bir Android sınıfının hangi yaşam döngüsü geri çağırma işlevinin eklendiği hakkında daha fazla bilgi edinmek için Bileşen ömürleri bölümüne bakın.

Hilt bağlamaları tanımlama

Alan yerleştirme işlemini gerçekleştirmek için Hilt'in ilgili bileşenden gerekli bağımlılıkların örneklerini nasıl sağlayacağını bilmesi gerekir. Bağlama, bir türün örneklerini bağımlılık olarak sağlamak için gerekli bilgileri içerir.

Hilt'e bağlama bilgileri sağlamanın bir yolu yapı eklemedir. Hilt'e bir sınıfın örneklerini nasıl sağlayacağını bildirmek için bir sınıfın kurucusundaki @Inject ek açıklamasını kullanın:

Kotlin

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

Java

public class AnalyticsAdapter {

  private final AnalyticsService service;

  @Inject
  AnalyticsAdapter(AnalyticsService service) {
    this.service = service;
  }
  ...
}

Bir sınıfın ek açıklamalı kurucusunun parametreleri, ilgili sınıfın bağımlılıklarıdır. Örnekte, AnalyticsAdapter bağımlılık olarak AnalyticsService değerine sahiptir. Bu nedenle Hilt, AnalyticsService örneklerinin nasıl sağlanacağını da bilmelidir.

Hilt modülleri

Bazen bir tür, oluşturucu enjekte edilemez. Bunun birkaç nedeni olabilir. Örneğin, bir arayüzde "yapılayıcı-yerleştirme" işlemi yapılamaz. Ayrıca, size ait olmayan bir türü (ör. harici bir kitaplıktan sınıf) derleyici-yerleştiremezsiniz. Bu gibi durumlarda, Hilt modüllerini kullanarak Hilt'e bağlama bilgileri sağlayabilirsiniz.

Hilt modülü, @Module ek açıklamasına sahip bir sınıftır. Bir Dagger modülü gibi, Hilt'e belirli türlerin örneklerini nasıl sağlayacağını bildirir. Dagger modüllerinin aksine, Hilt'e her modülün hangi Android sınıfında kullanılacağını veya yükleneceğini bildirmek için Hilt modüllerine @InstallIn ile ek açıklama eklemeniz gerekir.

Hilt modüllerinde sağladığınız bağımlılıklar, Hilt modülünü yüklediğiniz Android sınıfıyla ilişkili oluşturulmuş tüm bileşenlerde kullanılabilir.

@Binds ile arayüz örnekleri ekleme

AnalyticsService örneğini inceleyelim. AnalyticsService bir arayüzse oluşturucuyla ekleyemezsiniz. Bunun yerine, bir Hilt modülü içinde @Binds açıklaması bulunan soyut bir işlev oluşturarak Hilt'e bağlama bilgilerini sağlayın.

@Binds ek açıklaması, Hilt'e bir arayüz örneği sağlaması gerektiğinde hangi uygulamanın kullanılacağını bildirir.

Ek açıklamalı işlev, Hilt'e aşağıdaki bilgileri sağlar:

  • İşlev döndürme türü, Hilt'e işlevin hangi arayüzü sağladığını bildirir.
  • İşlev parametresi, hangi uygulamanın sağlanacağını Hilt'e bildirir.

Kotlin

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
}

Java

public interface AnalyticsService {
  void analyticsMethods();
}

// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
public class AnalyticsServiceImpl implements AnalyticsService {
  ...
  @Inject
  AnalyticsServiceImpl(...) {
    ...
  }
}

@Module
@InstallIn(ActivityComponent.class)
public abstract class AnalyticsModule {

  @Binds
  public abstract AnalyticsService bindAnalyticsService(
    AnalyticsServiceImpl analyticsServiceImpl
  );
}

Hilt'in bu bağımlılığı ExampleActivity öğesine eklemesini istediğiniz için AnalyticsModule Hilt modülüne @InstallIn(ActivityComponent.class) ek açıklaması eklenmiştir. Bu ek açıklama, AnalyticsModule kapsamındaki tüm bağımlılıkların uygulamanın tüm etkinliklerinde mevcut olduğu anlamına gelir.

@Provides ile örnek ekleme

Arayüzler, tür yapıcı ekleme işlemi yapamayacağınız tek durum değildir. Harici bir kitaplıktan (Retrofit, OkHttpClient veya Room veritabanları gibi sınıflar) geldiği için sınıfın sahibi değilseniz ya da örneklerin derleyici kalıbı ile oluşturulması gerekiyorsa da oluşturucu yerleştirme kullanılamaz.

Önceki örneği düşünün. AnalyticsService sınıfının doğrudan sahibi değilseniz Hilt modülü içinde bir işlev oluşturup bu işlevi @Provides ile not ederek Hilt'e bu tür örnekleri nasıl sağlayacağını bildirebilirsiniz.

Ek açıklamalı işlev, Hilt'e aşağıdaki bilgileri sağlar:

  • İşlev döndürme türü, Hilt'e işlevin ne tür örnekler sağladığını bildirir.
  • İşlev parametreleri, Hilt'e karşılık gelen türün bağımlılıklarını bildirir.
  • İşlev gövdesi, Hilt'e karşılık gelen türün bir örneğini nasıl sağlayacağını bildirir. Hilt, bu türden bir örnek sağlaması gerektiği her seferinde işlev gövdesini yürütür.

Kotlin

@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)
  }
}

Java

@Module
@InstallIn(ActivityComponent.class)
public class AnalyticsModule {

  @Provides
  public static AnalyticsService provideAnalyticsService(
    // Potential dependencies of this type
  ) {
      return new Retrofit.Builder()
               .baseUrl("https://example.com")
               .build()
               .create(AnalyticsService.class);
  }
}

Aynı tür için birden fazla bağlama sağlayın

Bağımlılıkla aynı türde farklı uygulamaları sağlamak için Hilt'e ihtiyaç duyduğunuz durumlarda, Hilt'e birden fazla bağlama sağlamanız gerekir. Niteleyicileri kullanarak aynı tür için birden fazla bağlama tanımlayabilirsiniz.

Niteleyici, bir tür birden fazla bağlama tanımlanmışsa o tür için belirli bir bağlamayı tanımlamak üzere kullandığınız ek açıklamadır.

Örneği düşünün. AnalyticsService çağrılarına müdahale etmeniz gerekiyorsa etkileyici içeren bir OkHttpClient nesnesi kullanabilirsiniz. Diğer hizmetler için çağrılara farklı bir şekilde müdahale etmeniz gerekebilir. Bu durumda, Hilt'e iki farklı OkHttpClient uygulamasını nasıl sağlayacağını bildirmeniz gerekir.

Öncelikle, @Binds veya @Provides yöntemlerine ek açıklama eklemek için kullanacağınız niteleyicileri tanımlayın:

Kotlin

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

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

Java

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
private @interface AuthInterceptorOkHttpClient {}

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
private @interface OtherInterceptorOkHttpClient {}

Ardından, Hilt'in her niteleyiciye karşılık gelen türün bir örneğini nasıl sağlayacağını bilmesi gerekir. Bu durumda, @Provides ile bir Hilt modülü kullanabilirsiniz. Her iki yöntem de aynı dönüş türüne sahiptir ancak niteleyiciler bunları iki farklı bağlama olarak etiketler:

Kotlin

@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()
  }
}

Java

@Module
@InstallIn(ActivityComponent.class)
public class NetworkModule {

  @AuthInterceptorOkHttpClient
  @Provides
  public static OkHttpClient provideAuthInterceptorOkHttpClient(
    AuthInterceptor authInterceptor
  ) {
      return new OkHttpClient.Builder()
                   .addInterceptor(authInterceptor)
                   .build();
  }

  @OtherInterceptorOkHttpClient
  @Provides
  public static OkHttpClient provideOtherInterceptorOkHttpClient(
    OtherInterceptor otherInterceptor
  ) {
      return new OkHttpClient.Builder()
                   .addInterceptor(otherInterceptor)
                   .build();
  }
}

Alana veya parametreye ilgili niteleyiciyle ek açıklama ekleyerek ihtiyacınız olan belirli türü yerleştirebilirsiniz:

Kotlin

// 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: AppCompatActivity() {

  @AuthInterceptorOkHttpClient
  @Inject lateinit var okHttpClient: OkHttpClient
}

Java

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

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

// As a dependency of a constructor-injected class.
public class ExampleServiceImpl ... {

  private final OkHttpClient okHttpClient;

  @Inject
  ExampleServiceImpl(@AuthInterceptorOkHttpClient OkHttpClient okHttpClient) {
    this.okHttpClient = okHttpClient;
  }
}

// At field injection.
@AndroidEntryPoint
public class ExampleActivity extends AppCompatActivity {

  @AuthInterceptorOkHttpClient
  @Inject
  OkHttpClient okHttpClient;
  ...
}

En iyi uygulama olarak, bir türe niteleyici eklerseniz bu bağımlılığı sağlamak için mümkün olan tüm yollara niteleyici ekleyin. Temel veya genel uygulamayı niteleyici olmadan bırakmak hataya açık olur ve Hilt'in yanlış bağımlı yerleştirmesine yol açabilir.

Hilt'teki önceden tanımlanmış niteleyiciler

Hilt, önceden tanımlanmış bazı niteleyiciler sağlar. Örneğin, uygulama veya etkinlikten Context sınıfına ihtiyaç duyabileceğinizden, Hilt @ApplicationContext ve @ActivityContext niteleyicilerini sağlar.

Örnekteki AnalyticsAdapter sınıfının etkinliğin bağlamına ihtiyacı olduğunu varsayalım. Aşağıdaki kod, etkinlik bağlamının AnalyticsAdapter öğesine nasıl sağlanacağını gösterir:

Kotlin

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

Java

public class AnalyticsAdapter {

  private final Context context;
  private final AnalyticsService service;

  @Inject
  AnalyticsAdapter(
    @ActivityContext Context context,
    AnalyticsService service
  ) {
    this.context = context;
    this.service = service;
  }
}

Hilt'te bulunan önceden tanımlanmış diğer bağlamalar için Bileşen varsayılan bağlamaları konusuna bakın.

Android sınıfları için oluşturulan bileşenler

Alan yerleştirme işlemi gerçekleştirebileceğiniz her Android sınıfı için @InstallIn ek açıklamasında referans verebileceğiniz ilişkili bir Hilt bileşeni vardır. Her Hilt bileşeni, kendi bağlamalarını karşılık gelen Android sınıfına eklemekten sorumludur.

Önceki örnekler, Hilt modüllerinde ActivityComponent kullanımını göstermiştir.

Hilt aşağıdaki bileşenleri sağlar:

Hilt bileşeni Şunun için enjektör:
SingletonComponent Application
ActivityRetainedComponent Yok
ViewModelComponent ViewModel
ActivityComponent Activity
FragmentComponent Fragment
ViewComponent View
ViewWithFragmentComponent View, @WithFragmentBindings ile ek açıklama ekledi
ServiceComponent Service

Bileşen ömürleri

Hilt, üretilen bileşen sınıflarının örneklerini ilgili Android sınıflarının yaşam döngüsünü izleyerek otomatik olarak oluşturur ve kaldırır.

Oluşturulan bileşen Oluşturulma zamanı İmha edilme tarihi
SingletonComponent Application#onCreate() Application kaldırıldı
ActivityRetainedComponent Activity#onCreate() Activity#onDestroy()
ViewModelComponent ViewModel oluşturuldu ViewModel kaldırıldı
ActivityComponent Activity#onCreate() Activity#onDestroy()
FragmentComponent Fragment#onAttach() Fragment#onDestroy()
ViewComponent View#super() View kaldırıldı
ViewWithFragmentComponent View#super() View kaldırıldı
ServiceComponent Service#onCreate() Service#onDestroy()

Bileşen kapsamları

Varsayılan olarak, Hilt'deki tüm bağlamalar kapsamsızdır. Bu, uygulamanız bağlama isteği her gönderdiğinde, Hilt'in gerekli türde yeni bir örnek oluşturduğu anlamına gelir.

Örnekte, Hilt başka bir türe bağımlılık olarak veya alan ekleme (ExampleActivity örneğinde olduğu gibi) aracılığıyla AnalyticsAdapter sağladığında, Hilt yeni bir AnalyticsAdapter örneği sağlar.

Ancak Hilt, bir bağlamanın belirli bir bileşen kapsamına alınmasına da izin verir. Hilt, bağlamanın kapsama dahil edildiği bileşenin her örneği için yalnızca bir kez kapsamlı bağlama oluşturur ve bu bağlamaya yönelik tüm istekler aynı örneği paylaşır.

Aşağıdaki tabloda, oluşturulan her bileşen için kapsam ek açıklamaları listelenmiştir:

Android sınıfı Oluşturulan bileşen Kapsam
Application SingletonComponent @Singleton
Activity ActivityRetainedComponent @ActivityRetainedScoped
ViewModel ViewModelComponent @ViewModelScoped
Activity ActivityComponent @ActivityScoped
Fragment FragmentComponent @FragmentScoped
View ViewComponent @ViewScoped
View, @WithFragmentBindings ile ek açıklama ekledi ViewWithFragmentComponent @ViewScoped
Service ServiceComponent @ServiceScoped

Örnekte, AnalyticsAdapter öğesini @ActivityScoped kullanarak ActivityComponent için kapsama alırsanız Hilt, ilgili etkinliğin ömrü boyunca aynı AnalyticsAdapter örneğini sağlar:

Kotlin

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

Java

@ActivityScoped
public class AnalyticsAdapter {

  private final AnalyticsService service;

  @Inject
  AnalyticsAdapter(AnalyticsService service) {
    this.service = service;
  }
  ...
}

AnalyticsService öğesinin, yalnızca ExampleActivity içinde değil, uygulamanın herhangi bir yerinde her zaman aynı örneğin kullanılmasını gerektiren bir dahili durumuna sahip olduğunu varsayalım. Bu durumda, AnalyticsService öğesinin SingletonComponent kapsamına alınması uygundur. Sonuç olarak, bileşenin AnalyticsService örneği sağlaması gerektiğinde her seferinde aynı örneği sağlar.

Aşağıdaki örnekte, bir bağlamanın Hilt modülündeki bir bileşene nasıl kapsam oluşturulacağı gösterilmektedir. Bir bağlamanın kapsamı, yüklendiği bileşenin kapsamıyla eşleşmelidir. Dolayısıyla bu örnekte, ActivityComponent yerine SingletonComponent konumuna AnalyticsService yüklemeniz gerekir:

Kotlin

// 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)
  }
}

Java

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

  @Singleton
  @Binds
  public abstract AnalyticsService bindAnalyticsService(
    AnalyticsServiceImpl analyticsServiceImpl
  );
}

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

  @Singleton
  @Provides
  public static AnalyticsService provideAnalyticsService() {
      return new Retrofit.Builder()
               .baseUrl("https://example.com")
               .build()
               .create(AnalyticsService.class);
  }
}

Hilt bileşen kapsamları hakkında daha fazla bilgi edinmek için Android ve Hilt'te kapsam oluşturma konusuna bakın.

Bileşen hiyerarşisi

Bir bileşene modül yüklemek, bileşen hiyerarşisinde söz konusu bileşendeki veya onun altındaki herhangi bir alt bileşendeki diğer bağlamalara bağımlı olarak bağlamalara erişilmesine olanak tanır:

ViewWithFragmentComponent, FragmentComponent altındadır. FragmentComponent ve ViewComponent, ActivityBileşen'in altındadır. ActivityBileşen,
    ActivityKeepedComponent altındadır. ViewModelComponent, ActivityKeepedBileşen'in altındadır. ActivityKeepedBileşen ve Hizmet Bileşeni, SingletonComponent altında yer alır.
Şekil 1. Hilt'in oluşturduğu bileşenlerin hiyerarşisi.

Bileşen varsayılan bağlamaları

Her Hilt bileşeni, Hilt'in kendi özel bağlamalarınıza bağımlılık olarak ekleyebileceği bir dizi varsayılan bağlama içerir. Bu bağlamaların, belirli bir alt sınıfa değil, genel etkinliğe ve parça türlerine karşılık geldiğini unutmayın. Bunun nedeni, Hilt'in tüm etkinlikleri eklemek için tek bir etkinlik bileşeni tanımı kullanmasıdır. Her etkinliğin bu bileşenin farklı bir örneği vardır.

Android bileşeni Varsayılan bağlamalar
SingletonComponent Application
ActivityRetainedComponent Application
ViewModelComponent SavedStateHandle
ActivityComponent Application, Activity
FragmentComponent Application, Activity Fragment
ViewComponent Application, Activity View
ViewWithFragmentComponent Application, Activity, Fragment, View
ServiceComponent Application, Service

Uygulama bağlamı bağlaması, @ApplicationContext kullanılarak da kullanılabilir. Örneğin:

Kotlin

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

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

Java

public class AnalyticsServiceImpl implements AnalyticsService {

  private final Context context;

  @Inject
  AnalyticsAdapter(@ApplicationContext Context context) {
    this.context = context;
  }
}

// The Application binding is available without qualifiers.
public class AnalyticsServiceImpl implements AnalyticsService {

  private final Application application;

  @Inject
  AnalyticsAdapter(Application application) {
    this.application = application;
  }
}

Etkinlik bağlamı bağlaması @ActivityContext ile de kullanılabilir. Örneğin:

Kotlin

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

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

Java

public class AnalyticsAdapter {

  private final Context context;

  @Inject
  AnalyticsAdapter(@ActivityContext Context context) {
    this.context = context;
  }
}

// The Activity binding is available without qualifiers.
public class AnalyticsAdapter {

  private final FragmentActivity activity;

  @Inject
  AnalyticsAdapter(FragmentActivity activity) {
    this.activity = activity;
  }
}

Hilt tarafından desteklenmeyen sınıflara bağımlılık ekleme

Hilt, en yaygın Android sınıflarını destekler. Ancak, Hilt'in desteklemediği sınıflarda alan yerleştirme işlemi gerçekleştirmeniz gerekebilir.

Bu gibi durumlarda, @EntryPoint ek açıklamasını kullanarak bir giriş noktası oluşturabilirsiniz. Giriş noktası, Hilt tarafından yönetilen kod ile yönetilmeyen kod arasındaki sınırdır. Bu, Hilt'in yönettiği nesnelerin grafiğine ilk girdiği noktadır. Giriş noktaları, Hilt'in bağımlılık grafiği içinde bağımlılıklar sağlamak için Hilt'in yönetemediği kodu kullanmasına olanak tanır.

Örneğin, Hilt içerik sağlayıcıları doğrudan desteklemez. Bir içerik sağlayıcının bazı bağımlılıkları almak için Hilt kullanmasını istiyorsanız istediğiniz her bağlama türü için @EntryPoint ek açıklamasına sahip bir arayüz tanımlamanız ve niteleyiciler eklemeniz gerekir. Ardından, giriş noktasının yükleneceği bileşeni belirtmek için aşağıdaki gibi @InstallIn ekleyin:

Kotlin

class ExampleContentProvider : ContentProvider() {

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

  ...
}

Java

public class ExampleContentProvider extends ContentProvider {

  @EntryPoint
  @InstallIn(SingletonComponent.class)
  interface ExampleContentProviderEntryPoint {
    public AnalyticsService analyticsService();
  }
  ...
}

Bir giriş noktasına erişmek için EntryPointAccessors adresindeki uygun statik yöntemi kullanın. Parametre, bileşen örneği veya bileşen tutucu görevi gören @AndroidEntryPoint nesnesi olmalıdır. Parametre olarak ilettiğiniz bileşenin ve EntryPointAccessors statik yönteminin @EntryPoint arayüzündeki @InstallIn ek açıklamasındaki Android sınıfıyla eşleştiğinden emin olun:

Kotlin

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()
    ...
  }
}

Java

public class ExampleContentProvider extends ContentProvider {

  @Override
  public Cursor query(...) {
    Context appContext = getContext().getApplicationContext();
    ExampleContentProviderEntryPoint hiltEntryPoint =
      EntryPointAccessors.fromApplication(appContext, ExampleContentProviderEntryPoint.class);
    AnalyticsService analyticsService = hiltEntryPoint.analyticsService();
  }
}

Bu örnekte, giriş noktası SingletonComponent uygulamasına yüklendiğinden, giriş noktasını almak için ApplicationContext öğesini kullanmanız gerekir. Almak istediğiniz bağlama ActivityComponent içindeyse bunun yerine ActivityContext öğesini kullanırsınız.

Yelek ve Hançer

Dagger bağımlılık ekleme kitaplığının üzerine derlenmiş olan Hilt, Dagger'ı Android uygulamalarına eklemenin standart bir yolunu sunar.

Dagger'la ilgili olarak, Hilt'in hedefleri şöyledir:

  • Android uygulamaları için Dagger ile ilgili altyapıyı basitleştirmek.
  • Kurulumu, okunabilirliği ve uygulamalar arasında kod paylaşımını kolaylaştırmak için standart bir bileşen ve kapsam seti oluşturmak için.
  • Test, hata ayıklama veya sürüm gibi çeşitli derleme türlerine farklı bağlamalar sağlamanın kolay bir yolunu sağlamak.

Android işletim sistemi, kendi çerçeve sınıflarının çoğunu örneklendirdiğinden, Android uygulamasında Dagger'ı kullanmak önemli miktarda ortak metin yazmanızı gerektirir. Hilt, bir Android uygulamasında Dagger'ın kullanımında kullanılan standart kodu azaltır. Hilt, aşağıdakileri otomatik olarak oluşturur ve sağlar:

  • Normalde elle oluşturmanız gereken, Android çerçeve sınıflarını Dagger ile entegre etmeye yönelik bileşenler.
  • Hilt'in otomatik olarak oluşturduğu bileşenlerle kullanılacak kapsam ek açıklamaları.
  • Application veya Activity gibi Android sınıflarını temsil eden önceden tanımlanmış bağlamalar.
  • @ApplicationContext ve @ActivityContext'yi temsil eden önceden tanımlanmış niteleyiciler.

Dagger ve Hilt kodu, aynı kod tabanında bir arada bulunabilir. Bununla birlikte, çoğu durumda Dagger'ın tüm kullanımlarını Android'de yönetmek için Hilt'i kullanmanız önerilir. Dagger'ı kullanan bir projeyi Hilt'e taşımak için taşıma rehberini ve Dagger uygulamanızı Hilt codelab'e taşıma belgesini inceleyin.

Ek kaynaklar

Hilt hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın.

Numuneler

Codelab uygulamaları

Bloglar