Hilt, Android için bir bağımlılık ekleme kitaplığıdır. Projenizde manuel bağımlılık ekleme işleminin ortak metinlerini azaltır. Manuel bağımlılık ekleme işlemini gerçekleştirmek için her sınıfı ve sınıfın bağımlılarını manuel olarak oluşturmanız ve bağımlılıkları yeniden kullanmak ve yönetmek için kapsayıcıları kullanmanız gerekir.
Hilt, projenizdeki her Android sınıfı için kapsayıcı sağlayarak ve yaşam döngülerini otomatik olarak yöneterek uygulamanızda DI'yi kullanmanın standart bir yolunu sunar. Hilt, derleme zamanında doğruluk, çalışma zamanında performans, ölçeklenebilirlik ve Dagger'ın sunduğu Android Studio desteğinden yararlanmak için popüler DI kitaplığı Dagger üzerine inşa edilmiştir. Daha fazla bilgi için Kılıç ve hançer başlıklı makaleyi inceleyin.
Bu kılavuzda, Hilt'in temel kavramları ve oluşturduğu kapsayıcılar açıklanmaktadır. Ayrıca, mevcut bir uygulamanın Hilt'i kullanacak şekilde nasıl başlatılacağını gösteren bir gösterim de yer alır.
Bağımlılık ekleme
Öncelikle hilt-android-gradle-plugin
eklentisini projenizin kök build.gradle
dosyasına ekleyin:
Eski
plugins { ... id 'com.google.dagger.hilt.android' version '2.51.1' apply false }
Kotlin
plugins { ... id("com.google.dagger.hilt.android") version "2.51.1" apply false }
Ardından Gradle eklentisini uygulayın ve aşağıdaki bağımlılıkları app/build.gradle
dosyanıza ekleyin:
Groovy
... plugins { id 'kotlin-kapt' id 'com.google.dagger.hilt.android' } android { ... } dependencies { implementation "com.google.dagger:hilt-android:2.51.1" kapt "com.google.dagger:hilt-compiler:2.51.1" } // Allow references to generated code kapt { correctErrorTypes true }
Kotlin
plugins { id("kotlin-kapt") id("com.google.dagger.hilt.android") } android { ... } dependencies { implementation("com.google.dagger:hilt-android:2.51.1") kapt("com.google.dagger:hilt-android-compiler:2.51.1") } // 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ğıdakileri ekleyin:
Groovy
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
ile ek açıklama eklenmiş bir Application
sınıfı içermelidir.
@HiltAndroidApp
, uygulamanız için uygulama düzeyinde bağımlılık kapsayıcısı görevi 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 nesne için bağımlılıklar sağlar. Ayrıca, uygulamanın üst bileşenidir. 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 kullanıma sunulduktan sonra @AndroidEntryPoint
ek açıklamasını içeren diğer Android sınıflarına bağımlılık 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
kullanılarak)ViewModel
(@HiltViewModel
kullanılarak)Activity
Fragment
View
Service
BroadcastReceiver
Bir Android sınıfına @AndroidEntryPoint
ile not eklerseniz ona bağlı Android sınıflarına da not eklemeniz gerekir. Örneğin, bir snippet'e ek açıklama eklerseniz bu snippet'i 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ık alabilir.
Bir bileşenden bağımlılık elde etmek için alan ekleme işlemi yapmak ü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ıflarda da ekleme kullanan başka temel sınıflar olabilir.
Bu sınıflar soyutlarsa @AndroidEntryPoint
ek açıklamasına ihtiyaç duymazlar.
Bir Android sınıfının hangi yaşam döngüsü geri çağırma işlevine yerleştirildiği hakkında daha fazla bilgi edinmek için Bileşen yaşam döngüleri bölümüne bakın.
Hilt bağlamalarını tanımlama
Hilt'in alan ekleme işlemini gerçekleştirebilmesi için ilgili bileşendeki gerekli bağımlılık örneklerini nasıl sağlayacağını bilmesi gerekir. Bağlama, bir türün örneklerini bağımlılık olarak sağlamak için gereken bilgileri içerir.
Hilt'e bağlama bilgilerini sağlamanın bir yolu yapıcı enjeksiyonudur. Hilt'e bir sınıfın örneklerini nasıl sağlayacağını söylemek için 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ı oluşturucusunun parametreleri, söz konusu sınıfın bağımlılıklarıdır. Örnekte, AnalyticsAdapter
boyutuna bağımlı öğe AnalyticsService
'tir. Bu nedenle Hilt, AnalyticsService
örneklerini nasıl sağlayacağını da bilmelidir.
Hilt modülleri
Bazen bir tür, kurucu tarafından eklenemez. Bu durum birden fazla nedenle gerçekleşebilir. Örneğin, bir arayüze kurucu enjeksiyonu yapamazsınız. Ayrıca, sahip olmadığınız bir türü (ör. harici bir kitaplıktaki sınıf) oluşturucu aracılığıyla ekleyemezsiniz. Bu gibi durumlarda, Hilt modüllerini kullanarak Hilt'e bağlama bilgileri sağlayabilirsiniz.
Hilt modülü, @Module
ile ek açıklama eklenmiş bir sınıftır. Bir Dagger modülü gibi, Hilt'e belirli türlerin örneklerini nasıl sağlayacağını bildirir. Dagger modüllerinden farklı olarak, Hilt modüllerini @InstallIn
ile ekleyerek Hilt'e her modülün hangi Android sınıfında kullanılacağını veya yükleneceğini bildirmeniz gerekir.
Hilt modüllerinde sağladığınız bağımlılar, Hilt modülünü yüklediğiniz Android sınıfıyla ilişkili olarak oluşturulan tüm bileşenlerde kullanılabilir.
@Binds ile arayüz örneklerini ekleme
AnalyticsService
örneğini inceleyin. AnalyticsService
bir arayüzse oluşturucu aracılığıyla ekleme yapamazsınız. Bunun yerine, Hilt modülü içinde @Binds
ile ek açıklamalı bir soyut 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ı söyler.
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 örneklerini sağladığını bildirir.
- İşlev parametresi, Hilt'e hangi uygulamanın sağlanacağını 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
içine enjekte etmesini istediğiniz için Hilt modülü AnalyticsModule
, @InstallIn(ActivityComponent.class)
ile ek açıklamaya sahiptir. Bu ek açıklama, AnalyticsModule
içindeki tüm bağımlılıkların, uygulamanın tüm etkinliklerinde kullanılabileceği anlamına gelir.
@Provides ile örnekleri yerleştirme
Bir türü oluşturucu aracılığıyla ekleyemeyeceğiniz tek durum arayüzler değildir.
Sınıfın sahibi siz değilseniz harici bir kitaplıktan (Retrofit, OkHttpClient
veya Oda veritabanları) geldiği ya da örneklerin derleyici kalıbı ile oluşturulması gerekiyorsa oluşturucu ekleme işlemi de yapılamaz.
Önceki örneği inceleyin. 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 ekleyerek Hilt'e bu türün örneklerini nasıl sağlayacağını söyleyebilirsiniz.
Notlandırılmış işlev, Hilt'e aşağıdaki bilgileri sağlar:
- İşlev dönüş türü, Hilt'e, işlevin hangi tür örneklerini sağladığını bildirir.
- İşlev parametreleri, Hilt'e ilgili türün bağımlılıklarını bildirir.
- İşlev gövdesi, Hilt'e ilgili türün bir örneğinin nasıl sağlanacağını söyler. Hilt, bu türden bir örnek sağlaması gerektiğinde her zaman 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ğlama
Bağımlılıklarla aynı türün farklı uygulamalarını sağlaması için Hilt'e ihtiyaç duyduğunuz durumlarda, Hilt'e birden çok bağlama sağlamanız gerekir. Sınıflandırıcılar ile aynı tür için birden fazla bağlama tanımlayabilirsiniz.
Niteleyici, bir tür için birden fazla bağlama tanımlandığında söz konusu türdeki belirli bir bağlamayı tanımlamak için kullandığınız bir ek açıklamadır.
Örneği düşünün. AnalyticsService
adresine yapılan aramaları engellemeniz gerekiyorsa engelleyici içeren bir OkHttpClient
nesnesi kullanabilirsiniz. Diğer hizmetler için aramaları farklı bir şekilde müdahale etmeniz gerekebilir. Bu durumda, Hilt'e OkHttpClient
için iki farklı uygulamanın nasıl sağlanacağını bildirmeniz gerekir.
Öncelikle, @Binds
veya @Provides
yöntemlerini açıklamak için kullanacağınız belirteçleri 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 Hilt modülü kullanabilirsiniz.
Her iki yöntemin de aynı döndürme türü vardır 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(); } }
Alanı veya parametreyi ilgili nitelikle ekleyerek ihtiyacınız olan belirli türü ekleyebilirsiniz:
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 nitelik eklerseniz bu bağımlılığı sağlamanın tüm olası yollarına nitelik ekleyin. Temelin veya ortak uygulamanın bir niteleyici olmadan bırakılması hataya açıktır ve Hilt'in yanlış bağımlılığı yerleştirmesine neden olabilir.
Hilt'te önceden tanımlanmış niteleyiciler
Hilt, önceden tanımlanmış bazı nitelikler sağlar. Örneğin, Context
sınıfına uygulama veya etkinlikten ihtiyaç duyabileceğiniz için Hilt, @ApplicationContext
ve @ActivityContext
niteleyicilerini sağlar.
Örnekteki AnalyticsAdapter
sınıfının etkinliğin bağlamına ihtiyaç duyduğunu varsayalım. Aşağıdaki kodda, AnalyticsAdapter
için etkinlik bağlamının nasıl sağlanacağı gösterilmektedir:
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 kullanılabilen diğer önceden tanımlanmış bağlamalar için Bileşen varsayılan bağlamaları başlıklı makaleyi inceleyin.
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 başvurabileceğiniz ilişkili bir Hilt bileşeni vardır.
Her Hilt bileşeni, bağlamalarını ilgili Android sınıfına enjekte etmekten sorumludur.
Önceki örnekler, Hilt modüllerinde ActivityComponent
kullanımını göstermektedir.
Hilt aşağıdaki bileşenleri sağlar:
Sap bileşeni | Şunlar için enjeksiyon cihazı: |
---|---|
SingletonComponent |
Application |
ActivityRetainedComponent |
Yok |
ViewModelComponent |
ViewModel |
ActivityComponent |
Activity |
FragmentComponent |
Fragment |
ViewComponent |
View |
ViewWithFragmentComponent |
View , @WithFragmentBindings ile ek açıklamalı |
ServiceComponent |
Service |
Bileşen kullanım ömrü
Hilt, oluşturulan bileşen sınıflarının örneklerini ilgili Android sınıflarının yaşam döngüsüne göre otomatik olarak oluşturur ve yok eder.
Oluşturulan bileşen | Oluşturulma zamanı | Kaldırıldığı tarih |
---|---|---|
SingletonComponent |
Application#onCreate() |
Application imha edildi |
ActivityRetainedComponent |
Activity#onCreate() |
Activity#onDestroy() |
ViewModelComponent |
ViewModel oluşturuldu |
ViewModel imha edildi |
ActivityComponent |
Activity#onCreate() |
Activity#onDestroy() |
FragmentComponent |
Fragment#onAttach() |
Fragment#onDestroy() |
ViewComponent |
View#super() |
View imha edildi |
ViewWithFragmentComponent |
View#super() |
View imha edildi |
ServiceComponent |
Service#onCreate() |
Service#onDestroy() |
Bileşen kapsamları
Varsayılan olarak Hilt'teki tüm bağlamaların kapsamı kaldırılır. Bu, uygulamanız bağlamayı her istediğinde Hilt'in gerekli türün yeni bir örneğini oluşturduğu anlamına gelir.
Örnekte, Hilt her AnalyticsAdapter
türünü başka bir türe bağımlı olarak veya alan ekleme yoluyla (ExampleActivity
'te olduğu gibi) sağladığında yeni bir AnalyticsAdapter
örneği sağlar.
Ancak Hilt, bağlamanın belirli bir bileşenle sınırlandırılmasına da olanak tanır. Hilt, bağlamanın kapsama dahil olduğu 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şenin 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çıklamalı |
ViewWithFragmentComponent |
@ViewScoped |
Service |
ServiceComponent |
@ServiceScoped |
Örnekte, @ActivityScoped
kullanarak AnalyticsAdapter
'ü ActivityComponent
'e göre kapsamlandırı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
sınıfının, yalnızca ExampleActivity
'te değil, uygulamanın her yerinde her zaman aynı örneğin kullanılmasını gerektiren bir dahili durumuna sahip olduğunu varsayalım. Bu durumda, AnalyticsService
sınıfının kapsamını SingletonComponent
olarak belirlemek uygundur. Sonuç olarak, bileşenin AnalyticsService
örneği sağlaması gerektiğinde her zaman aynı örneği sağlar.
Aşağıdaki örnekte, Hilt modülündeki bir bileşene bağlamanın nasıl kapsamlandırılacağı gösterilmektedir. Bağlantının kapsamı, yüklendiği bileşenin kapsamıyla eşleşmelidir. Bu nedenle, bu örnekte AnalyticsService
'ü ActivityComponent
yerine SingletonComponent
içine 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 başlıklı makaleyi inceleyin.
Bileşen hiyerarşisi
Bir modülü bir bileşene yüklediğinizde, bu modülün bağlamalarına, bileşen hiyerarşisinde bu bileşendeki veya altındaki herhangi bir alt bileşendeki diğer bağlamaların bağımlılığı olarak erişilebilir:
Bileşen varsayılan bağlamaları
Her Hilt bileşeni, Hilt'in kendi özel bağlamalarınıza bağımlılık olarak ekleyebildiği bir dizi varsayılan bağlama ile birlikte gelir. Bu bağlamaların herhangi bir belirli 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 etkinlikte 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ğlama özelliği @ApplicationContext
kullanılarak da kullanılabilir.
Örnek:
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ğlama özelliği @ActivityContext
kullanılarak da 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ı için destek sunar. Ancak Hilt'in desteklemediği sınıflarda alan ekleme yapmanız 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, kodun Hilt'in yönettiği nesnelerin grafiğine ilk girdiği noktadır. Giriş noktaları, Hilt'in bağımlılık grafiğinde bağımlılık sağlamak iç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'i kullanmasını istiyorsanız istediğiniz her bağlama türü için @EntryPoint
ile açıklama eklenen bir arayüz tanımlamanız ve niteleyiciler eklemeniz gerekir. Ardından, giriş noktasının yükleneceği bileşeni belirtmek için @InstallIn
öğesini aşağıdaki şekilde 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
'teki uygun statik yöntemi kullanın. Parametre, bileşen örneği veya bileşen tutucusu olarak işlev 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
'a yüklendiği için giriş noktasını almak üzere ApplicationContext
kullanmanız gerekir. Almak istediğiniz bağlama ActivityComponent
içinde olsaydı bunun yerine ActivityContext
öğesini kullanırsınız.
Kılıç sapı ve hançer
Hilt, Dagger bağımlılık enjeksiyon kitaplığının üzerine inşa edilmiştir ve Dagger'ı Android uygulamasına dahil etmenin standart bir yolunu sunar.
Dagger ile ilgili olarak, Hilt'in hedefleri aşağıdaki gibidir:
- 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 amacıyla standart bir bileşen ve kapsam grubu oluşturmak için kullanılır.
- Test, hata ayıklama veya sürüm gibi çeşitli derleme türlerine farklı bağlamalar sağlamanın kolay bir yolunu sunmak amacıyla.
Android işletim sistemi, kendi çerçeve sınıflarının çoğunu örneklendirdiği için Android uygulamasında Dagger'ı kullanmak çok fazla standart kod yazmanızı gerektirir. Hilt, Android uygulamasında Dagger'ı kullanmayla ilgili ortak metin kodlarını azaltır. Hilt, aşağıdakileri otomatik olarak oluşturur ve sağlar:
- Android çerçeve sınıflarını Dagger ile entegre etmek için bileşenler. Aksi takdirde bunları manuel olarak oluşturmanız gerekir.
- Hilt'in otomatik olarak oluşturduğu bileşenlerle kullanılacak kapsam ek açıklamaları.
Application
veyaActivity
gibi Android sınıflarını temsil etmek için önceden tanımlanmış bağlamalar.@ApplicationContext
ve@ActivityContext
değerlerini temsil edecek önceden tanımlanmış niteleyiciler.
Dagger ve Hilt kodu, aynı kod tabanında bir arada bulunabilir. Ancak çoğu durumda, Android'de Dagger'ı kullanmanızın tamamını yönetmek için Hilt'i kullanmak en iyisidir. Dagger kullanan bir projeyi Hilt'e taşımak için taşıma rehberini ve Dagger uygulamanızı Hilt codelab'e taşıma başlıklı makaleleri inceleyin.
Ek kaynaklar
Hilt hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın.
Örnekler
Codelab uygulamaları
Bloglar
- Hilt ile Android'de bağımlılık ekleme
- Android ve Hilt'te kapsam belirleme
- Hilt hiyerarşisine bileşen ekleme
- Google I/O uygulamasını Hilt'e taşıma