Open1

Hilt導入

るるすたるるすた

Hiltとは

Androidアプリ開発における 依存性注入(DI: Dependency Injection) を
簡単に実現するための ライブラリ
導入するとViewModel・Repository・データ層の管理と連携がしやすくなります。

どういうこと?

viewModelを呼び出すときのコード

val viewModel=hiltViewModel<MyViewModel>()

これでOK!
Factoryも手書きViewModelProvider も不要!

他にもテストしやすくなることも利点
FakeやMockを @Provides で簡単に切り替え
HiltTestRunnerで統合テストにも対応

Hiltの導入のステップ

  1. Hilt用依存関係の追加
  2. Application クラスの作成:
    @HiltAndroidAppアノテーションを付与したカスタム Application クラスを作成
  3. AndroidManifest.xml の変更
    カスタム Applicationクラスを使用するように設定
  4. ViewModel のHilt対応
    ViewModelをHiltで注入できるように設定
  5. Composable での ViewModel の取得
    hiltViewModel() を使用して ViewModelを取得するように変更

1.Hilt用依存関係の追加

いつもの依存関係ですね。今回はプラグインも追加します。

libs.version.toml

[versions]

hilt = "2.51.1"

[libraries]

hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version = "1.2.0" }
hilt-testing = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" }

[plugins]

hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }

build.gradle.kts(Project:XXXXXX)←プロジェクトレベル!

プラグインを追加するので、プロジェクトレベルのGradleファイルに設定を入れます
追加とコメントした部分を追加します

plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
    alias(libs.plugins.kotlin.compose) apply false
    alias(libs.plugins.hilt.android) apply false    //追加
}

buildgradle.kts(Module:App)

こっちはいつものです。pluginsに設定が必要なのと、kapt単体の設定がいるようです。

plugins {
    //他プラグイン
    id("kotlin-kapt")
    id("com.google.dagger.hilt.android")
}

dependencies {
    //Hilt
    implementation(libs.hilt.android)
    kapt(libs.hilt.compiler)
    implementation(libs.hilt.navigation.compose)
    //Hiltテスト用
    androidTestImplementation(libs.hilt.testing)
    kaptAndroidTest(libs.hilt.compiler)
   //他設定
}

kapt {
    correctErrorTypes = true
}

→Sync Now!!!!

2. Application クラスの作成:

@HiltAndroidAppアノテーションを付与したカスタム Application クラスを作成
場所はMainActivity.ktと同じ場所。
一旦、中身空っぽです。

@HiltAndroidApp
class EasyPromptApplication : Application() {
}

3. AndroidManifest.xml の変更

2で作成したApplicationクラスを使用するように設定

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:name=".EasyPromptApplication"
・・・・・

4. MainActivity.ktのHilt対応

MainActivityにHilt用の@AndroidEntryPointアノテーションをつける。
このActivityはHiltから依存をもらいますという宣言。
つけないとhiltviewModel()ってやった瞬間クラッシュするようです。

+ @AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            RurustaApp()
        }
    }
}

5. ViewModel のHilt対応

ViewModel をHiltで注入できるように、@HiltViewModelアノテーションを追加し、
コンストラクタに @Inject アノテーションを付与

import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class PromptViewModel @Inject constructor():ViewModel() {
    //プロパティとかメソッドとか書く
}

【必要な場合のみ】Repositoryの提供

以前作成したUserPreferencesRepository(初回起動時のみ表示するダイアログのフラグを管理する場所)をHiltで注入できるようにするためのモジュールを作成
プロジェクト>di>AppModule.kt

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

    @Singleton
    @Provides
    fun provideUserPreferencesRepository(@ApplicationContext context: Context): UserPreferencesRepository {
        return UserPreferencesRepository(context)
    }
}

【必要な場合のみ】MainActivity.ktの更新

MainActivity.kt を変更して、@AndroidEntryPoint アノテーションを追加し、UserPreferencesRepositoryをHiltで注入するように変更
また、EasyPromptAppにViewModelを渡す部分についても修正

+@AndroidEntryPoint
class MainActivity : ComponentActivity() {

+    @Inject
    lateinit var userPreferencesRepository: UserPreferencesRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
+            val promptViewModel: PromptViewModel = hiltViewModel()
            EasyPromptTheme {
                EasyPromptApp(
                    userPreferencesRepository = userPreferencesRepository,
                    promptViewModel = promptViewModel
                )
            }
        }
    }
}

6. Composable での ViewModel の取得

  hiltViewModel() を使用して ViewModelを取得するように変更