LoginSignup
3
9

More than 3 years have passed since last update.

【はじめてのHilt】Hilt + Room で依存関係注入してみた

Last updated at Posted at 2021-03-12

この記事について

MVVMでのAndroidのDIライブラリであるHiltの使い方を、同じJetpackライブラリであるRoomを用いて解説します。
今回はRoomの構築部分は割愛します。

Hiltの依存関係を追加

まずは、Hiltプラグインをプロジェクトのルートに追加します。

build.gradle
buildscript {
    ...
    dependencies {
        ...
        def hilt_version = '2.33-beta'
        classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
    }
}

次に、app/build.gradleファイルに依存関係を追加します。

app/build.gradle
plugins {
    ...
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

dependencies {
    def hilt_version = "2.33-beta"
    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
}

Java8を有効にするには、同じくapp/build.gradleに以下を追加

app/build.gradle
android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

ApplicationクラスにHiltを導入

Applicationを継承した自作のApplicationクラスに@HiltAndroidAppをつけます。

MyApplication.kt
@HiltAndroidApp
class MyApplication : Application() { ... }

作成したMyApplicationをAndroidManifest.xmlに追記します。

AndroidManifest.xml
<application
        android:name="(プロジェクト名).MyApplication"

これにより、HiltコンポーネントはApplication オブジェクトのライフサイクルにアタッチされ、依存関係を提供します。
Applicationはアプリの親コンポーネントであることから、他のコンポーネントが依存関係にアクセスできるようになります。

Androidクラスに依存関係を注入する

Application クラスで Hilt がセットアップされ、アプリケーションレベルのコンポーネントが利用可能になると、@AndroidEntryPoint アノテーションが付けられた他の Android クラスに依存関係を提供できるようになります。

MyActivity.kt
@AndroidEntryPoint
class MyActivity : AppCompatActivity() {...}

Fragmentを利用する際も同様に@AndroidEntryPointをつけます。

MyFragment.kt
@AndroidEntryPoint
class MyFragment : Fragment() {...}

※Fragmentの親となるActivityにも@AndroidEntryPointを設置することを忘れないように!!

Hiltを使ってViewModelオブジェクトを注入する

次に、ActivityやFragmentと紐づいているViewModelに依存関係を注入していきます。ViewModelには@HiltViewModelをつけます。
また、このときにViewModelからRepositoryを参照・使用するために依存関係を注入していきますが、この方法としては@Injectを使った以下の2つがあります。

・Constructor Injection
・Field Injection

以上2つの注入の仕方について説明します。

Constructor Injection

MyViewModel.kt
@HiltViewModel
class MyViewModel @Inject constructor(
    private val repository: MyRepository
): ViewModel() {...}

本記事ではこの後、Constructor Injectionを使っていきます。

Field Injection

MyViewModel.kt
@HiltViewModel
class MyViewModel(): ViewModel() {
    @Inject lateinit var repository: MyRepository
}

RepositoryにRoom Daoを注入

続いてRepositoryをみていきましょう。
ここではRoomのDaoをRepositoryに注入し、Daoにあるメソッドを呼び出します。注入の仕方は前述のViewModelと同じ@Injectで注入できます。

MyRepository.kt
class MyRepository @Inject constructor(private val myDao: MyDao) {...}

これでRepositoryからMyDaoを呼び出すことが可能になります。
例えばMyDao内でSELECTしてきた次のようなデータを

MyDao.kt
@Dao
interface MyDao {
    @Query("SELECT * FROM user")
    fun findAll(): List<User>
}

Repositoryからは

MyRepository.kt
class MyRepository @Inject constructor(private val myDao: MyDao) {
    fun findAllInDB() = myDao.findAll()
}

これで呼び出し完了です!!

Hiltモジュールの作成

Hiltモジュールでは@Moduleをつけたクラスから、特定の型のインスタンスの提供方法を Hilt に知らせることができます。
ここではRoom Databaseの構築と、Daoの実装を行います。

MyModule.kt
@Module
@InstallIn(SingletonComponent::class)
object MyModule {

    @Singleton
    @Provides
    fun provideDatabase(
        @ApplicationContext context: Context
    ) = Room.databaseBuilder(context, AppDatabase::class.java, "user_db").build()

    @Singleton
    @Provides
    fun provideDao(db: AppDatabase) = db.myDao()
}

・@InstallIn:各モジュールが使用またはインストールされる Android クラスを知らせます。ここではSingletonComponentを用いることで、アプリケーション内のどこからでもアクセス可能になります。その他のComponentについてはAndroid Developersをご覧ください。

・@Singleton:同じインスタンスを使いまわすことができます。このアノテーションを外すと、依存注入のたびに新しいインスタンスが生成されます。

・@Provides:このアノテーションをつけた関数のインスタンスを提供します。Room等のDBのほか、RetrofitやOkHttpClientのBuildでインスタンスを生成するときも同様です。

とりあえずはこれでHiltを使ったRoomの依存関係注入は完了です!
同じようにHilt + Roomを使ったアプリをGitHubで公開しているので、こちらもご覧ください。
GitHub

参考記事

Hilt and Jetpack integrations
Dependency injection with Hilt
How to create and use a Room Database in Kotlin [Dagger-Hilt]

3
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
9