# Hilt 快速使用筆記 - 基本 [TOC]  ## Gradle 設定 1. Hilt 使用 [Java 8 功能](https://developer.android.com/studio/write/java8-support?hl=zh-cn) 以上 2. project/ **build.gradle** 1. `plugins` 3. **app/build.gradle** 1. 啟用允許引用產生的程式碼 `correctErrorTypes true` 2. `dependencies` ## 基本常用 Annotation Type ### `@HiltAndroidApp` 1. 必須設定在繼承`Application()`的類別上 2. 觸發代碼生成的操作,包含提供 application-level dependency 容器 3. 產生的Hilt元件附加到Application物件的生命週期並提供依賴項目 ```kotlin @HiltAndroidApp class ExampleApplication : Application() { ... } ``` ### `@AndroidEntryProint` 1. Application class 有設定`@HiltAndroidApp`,設定Annotation可以將相依性注入 Android class 2. Hilt的入口點 ```kotlin @AndroidEntryPoint class ExampleActivity : AppCompatActivity() { ... } ``` ### **`@Inject`** 1. 宣告注入的依賴物件,設定private的會導致編譯錯誤 2. 需相應**`@Inject`**要注入的物件 ```kotlin @AndroidEntryPoint class ExampleActivity : AppCompatActivity() { @Inject lateinit var analytics: AnalyticsAdapter ... } ``` ```kotlin class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... } ``` ## 不能透過構造函數注入型別 > cannot be constructor-injected a type,Hilt can provide with binding information by using Hilt modules > Hilt modules 要annotated with`@Module`、`@InstallIn` 1. interface → `@Binds` 2. external library → `@Provide` 3. `@Binds` vs `@Provide` ### `@Module` - 告訴Hilt 知道如何提供某些類型的實例 ### `@InstallIn` - 有**`@Module` 類別以**`@InstallIn`告訴 Hilt 每個模組將在哪個 Android 類別中關聯的所有產生的元件中使用和安裝 - Android 類別中關聯元件:`ActivityComponent::class`、`SingletonComponent::class` ### `@Binds` - 告訴 Hilt 在需要提供**介面實例**時要使用`@Inject` constructor - `@Binds` function 參數告訴 Hilt 提供哪個實作 - `@Binds` function 回類型告訴 Hilt 該函數提供哪個介面的實例 ```kotlin interface AnalyticsService { fun analyticsMethods() } // 實作介面 class AnalyticsServiceImpl @Inject constructor( ... ) : AnalyticsService { ... } @Module @InstallIn(ActivityComponent::class) abstract class AnalyticsModule { @Binds abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl ): AnalyticsService } ``` ### `@Provide` 1. 外部套件 like [Retrofit](https://square.github.io/retrofit/), [`OkHttpClient`](https://square.github.io/okhttp/), or [Room databases](https://developer.android.com/topic/libraries/architecture/room)、或是設計模式之一的 [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern). 2. `@Provides` function 3. `@Provides` function 回類型告訴 Hilt 提供的實例 ```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) } } ``` ## **Provide multiple bindings for the same type** ### `@qualifiers` - 自定義 annotate class 用於 @Binds 或 @Provides 方法的, - 類別前加上`@Qualifer`、`@Retention(AnnotationRetention.BINARY)` 1. **範例 `@Provides`** - Hilt 模組與`@Provides` 兩種方法具有相同的傳回類型,但`@Qualifer`定義的annotate將它們標記為兩個不同的綁定 - 更換自定義Annoctation ```kotlin @Qualifier @Retention(AnnotationRetention.BINARY) annotation class AuthInterceptorOkHttpClient @Qualifier @Retention(AnnotationRetention.BINARY) annotation class OtherInterceptorOkHttpClient ``` ```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() } } @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 } ``` 2. 範例 `@Binds` - class 取得 `@Inject` 建構子的參數在更換自定義Annoctation `@BindElectricEngine` ```kotlin @Qualifier @Retention(AnnotationRetention.BINARY) annotation class BindElectricEngine @Qualifier @Retention(AnnotationRetention.BINARY) annotation class BindHybridEngine ``` ```kotlin @Module @InstallIn(ActivityComponent::class) abstract class EngineModule { @BindElectricEngine @Binds abstract fun bindElecEngine(engine: ElectricEngine):Engine @BindHybridEngine @Binds abstract fun bindHybridEngine(engine: HybridEngine):Engine } class Car @Inject constructor( @BindElectricEngine private val engine: Engine ) { fun start(){ engine.start() } } ``` # 參考網址 1. [將 Dagger 應用程式遷移到 Hilt](https://developer.android.com/codelabs/android-dagger-to-hilt?hl=zh-cn) 2. [Dependency injection with Hilt ](https://developer.android.com/training/dependency-injection/hilt-android?hl=zh-cn) 3. [Android的依賴注入-Hilt函式庫](https://jimmy4302001.medium.com/android%E7%9A%84%E4%BE%9D%E8%B3%B4%E6%B3%A8%E5%85%A5-hilt%E5%87%BD%E5%BC%8F%E5%BA%AB-2514c1f2fa65)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up