【正社員】還元率83%【フリーランス】マージン一律5万円で案件をご紹介させていただきます。 詳細はこちら

【Android】<Kotlin>Hiltを使ったDI(依存性注入)のやり方をわかりやすく解説!

【Android】<Kotlin>Hiltを使ったDI(依存性注入)のやり方をわかりやすく解説!
すだ

みなさまこんにちは〜!
メモリアインクのすだです。

今回は、Hiltというライブラリを使ったDI(依存性注入)について、詳しく解説していきます!

この記事を読んでわかること…
・Hiltとは?
・Hiltを使ったDI(依存性注入)のやり方

DI(依存性注入)の基本については、以下の記事で解説しておりますので、ぜひ一緒にご覧ください。

目次

環境

  • Kotlin (ver 1.9.0)
  • Android Studio (Giraffe | 2022.3.1 Patch 3)

Hiltとは?

Hiltは、Googleが提供するDIライブラリです。
https://developer.android.com/training/dependency-injection/hilt-android?hl=ja

Androidアプリ開発に最適化されており、以下の特徴があります:

  • @Inject などのアノテーションで簡単にDIができる
  • ActivityやViewModel、Fragmentに自動的に依存関係を注入可能
  • テスト支援も充実
  • Jetpackライブラリと高い互換性

手動DIでは依存関係の管理がどんどん大変になりますが、
Hiltを使えばその多くを自動化できるため、よりスムーズに開発できます。

Hiltの導入方法(セットアップ)

Hiltライブラリを使用するために、build.gradleに以下の設定を行います。

プロジェクトレベルのbuild.gradle▼

buildscript {
    dependencies {
        classpath "com.google.dagger:hilt-android-gradle-plugin:2.48"
    }
}

モジュールレベルのbuild.gradle▼

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

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

HiltのバージョンはKotlinのバージョンに依存するので、導入時はバージョンをよく確認してください。

そして、Applicationクラスに以下のアノテーションを付与してください。▼

@HiltAndroidApp
class MyApplication : Application()

Hiltを使ったDIのやり方

たとえば、以下の「手動でDIを行った処理」があるとします。

手動DI ▼

// 依存クラス
class ApiClient {
    fun fetchUser(): String = "Taro"
}

// 依存を使うクラス
class UserRepository(private val apiClient: ApiClient) {
    fun getUser(): String = apiClient.fetchUser()
}

// 呼び出し処理
class MainActivity : AppCompatActivity() {
    lateinit var userRepository: UserRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val apiClient = ApiClient()
        val userRepository = UserRepository(apiClient)
        println(userRepository.getUser()) // → Taro
    }
}

これを、Hiltを使うように変更してみます。▼

1. ApiClient@Inject を付ける

class ApiClient @Inject constructor() {
    fun fetchUser(): String = "Taro"
}

依存クラスのコンストラクタに @Inject(= 依存を注入できるマーク)を付けることで、Hiltがこのクラスのインスタンスを自動で生成できるようになります。

Kotlinでは通常、constructor() の記述は省略できますが、Hiltでは @Inject constructor() という形で明示的に書く必要があります。

これにより、「このコンストラクタを使って ApiClient を作成してください」とHiltに指示できます。

2. UserRepository にも @Inject を付ける

class UserRepository @Inject constructor(private val apiClient: ApiClient) {
    fun getUser(): String = apiClient.fetchUser()
}

UserRepositoryApiClient に依存しているため、同様に @Inject constructor(...) を付けます。
これにより、Hiltが ApiClient を先に生成し、それを使って UserRepository を自動で組み立ててくれます。

つまりこの記述は、「このコンストラクタを使って UserRepository を作ってください」とHiltに伝えていることになります。

3. MainActivity@AndroidEntryPoint を付ける

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var userRepository: UserRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        println(userRepository.getUser()) // ← Hiltが自動で注入
    }
}

@AndroidEntryPoint は、「このクラスでHiltによる依存注入を使いたい」と宣言するアノテーションです。
このマークをクラス名の上に付けることで、Hiltが MainActivity をDI(依存性注入)の対象として認識します。

さらに、注入したいプロパティには @Inject を付けます。
これにより、Hiltが UserRepository のインスタンスを自動で生成して userRepository に依存を注入してくれます。

依存関係の流れを図解すると:

MainActivity
   ↓ @Inject
UserRepository
   ↓ @Inject constructor(apiClient)
ApiClient
   ↑ @Inject constructor ← Hiltがここも作る

このように、MainActivity は UserRepository を使い、
UserRepository は ApiClient を使います。

このようにHiltは依存をたどって必要なものを全部作ってくれるのです。

Hiltの使い所

「Hiltの使い所」は大きく3つのパターンに分類できます。

constructor や プロパティ

これは先ほどご紹介した例です。
@Inject constructor(...) / @Inject lateinit var ...といった形でコンストラクタやプロパティにInjectアノテーションをつけてあげることによるDI。Hiltがインスタンスを作ったり、注入するために使う基本と言えます。

class ApiClient @Inject constructor() { ... }

class MainActivity : AppCompatActivity() {
    @Inject lateinit var apiClient: ApiClient
}

ViewModel クラス

Hiltは、ViewModelを含む複数のJetpack コンポーネントと公式に統合されているため相性がとても良いです。
ViewModelに依存を注入するには、@HiltViewModelという専用のアノテーションが必要です。

@HiltViewModel
class UserViewModel @Inject constructor(
    private val repository: UserRepository
) : ViewModel() {

    fun getUserName(): String = repository.fetchUser()
}

より詳しい実装に関しては以下の記事でご紹介しておりますのでぜひご覧ください。

object

Hiltで外部ライブラリや手動インスタンスを注入したいとき、@Module + @Providesを使ってDIできます。

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

    @Provides
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .build()
    }
}

より詳しい実装に関しては以下の記事でご紹介しておりますのでぜひご覧ください。

まとめ

おつかれさまでした。いかがでしたでしょうか!

はじめてHiltなどのDIライブラリを導入する方は少し違和感を感じるかもしれませんが、
慣れてくると使いやすさを感じるかと思います!

すだ

技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
を通じて、
自分の市場価値をさらに向上させてみませんか?

それではまた次回の記事でお会いしましょう!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

弊社テックブログをご愛読いただきありがとうございます。
当テックブログを運用している株式会社メモリアインクは、
【正社員】還元率83%
【フリーランス】マージン一律5万円で案件のご紹介
と、エンジニアの皆様に分かりやすい形で稼げる仕組みを構築し提供させていただいております。

コメント

コメントする

目次