3
0

More than 3 years have passed since last update.

Dagger Hilt触ってみた

Posted at

はじめに

巷で噂のDagger Hiltをようやく触ってみました。Codelabを一通り終わったので、実際に過去の記事でDaggerを使ってDIしたのですがそれをHiltに移行した手順をまとめます。

Gradle

build.gradle
    // build.gradle (Project)
    ext.hilt_version = '2.28-alpha'
    dependencies {
        classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
    }

build.gradle
    // build.gradle (App)
    // Dagger_hilt
    implementation "com.google.dagger:hilt-android:$hilt_version" // 必須
    kapt "com.google.dagger:hilt-android-compiler:$hilt_version" // 必須

    def dagger_hilt_view_model_version = "1.0.0-alpha01"
    implementation "androidx.hilt:hilt-lifecycle-viewmodel:${dagger_hilt_view_model_version}"
    kapt "androidx.hilt:hilt-compiler:${dagger_hilt_view_model_version}"

今回は、ViewModelを使うので、hilt-compilerhilt-lifecycle-viewmodelを追加した。

実装

移行の順番は、
1. Application & @Singleton
2. Fragment & Activity

ということで、Applicationを見てみましょう。

Application

Hiltに移行する前のコードがこちらです。Applicationでは、独自に設計したComponentをインスタンス化していました。しかし、Hiltでは標準のComponentが用意されていてComponentを定義する必要がなくなったらしい。

TodoApplication.kt
class TodoApplication : Application() {
    companion object {
        lateinit var component: AppComponent private set
    }

    override fun onCreate() {
        super.onCreate()
        component = DaggerAppComponent.factory().create(applicationContext)
    }
}

HiltではApplication@HiltAndroidAppアノテーションをつけて定義します。

TodoApplication.kt
@HiltAndroidApp
class TodoApplication : Application() {
//    companion object {
//        lateinit var component: AppComponent private set
//    }
//
//    override fun onCreate() {
//        super.onCreate()
//        component = DaggerAppComponent.factory().create(applicationContext)
//    }
}

このコードからわかるようにComponent自体もいらないので、AppComponentを削除します。

AppComponent.kt
//@Singleton
//@Component(
//    modules = [
//        DatabaseModule::class
//    ]
//)
//interface AppComponent {
//
//    @Component.Factory
//    interface Factory {
//        fun create(@BindsInstance context: Context): AppComponent
//    }
//    fun mainViewModel(): MainViewModel
//}

Activity

元々あったComponentを削除したので、ActivityやFragmentにInjectできるように、@AndroidEntryPointアノテーションを記述しなければならない。

MainActivity.kt
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

今回は、Fragmentが登場しませんが、もしFragmentにInjectしたいときはそれを所持するActivityにも@AndroidEntryPointを付ける必要があります。

Module

Moduleの定義方法は、@InstallIn(ApplicationComponent::class)アノテーションをつける必要があります。@InstallInアノテーションでHiltが生成するComponentにModuleを紐付けます。

DatabaseModule.kt
@InstallIn(ApplicationComponent::class)
@Module
class DatabaseModule() {


    @Singleton
    @Provides
    fun provideTodoDatabase(@ApplicationContext context: Context) =
        Room.databaseBuilder(context,
            TodoDatabase::class.java,
            "database_name")
            .build()

    @Singleton
    @Provides
    fun provideTodoDao(todoDatabase: TodoDatabase) = todoDatabase.todoDao()
}

移行前は、ContextをComponentのインスタンス生成する時に渡していたがそれをする必要がなくなりました。 すでにBinding済みのContextを使用することができます。@ApplicationContext@ActivityContextをつけるだけで使用できます。

ViewModel

ViewModelをHiltを使ってDIする場合、constructorに@ViewModelInjectアノテーションをつけます。

MainViewModel.kt
class MainViewModel @ViewModelInject constructor(private val repository: TodoRepository) : ViewModel() {

最後Activityに、

MainActivity.kt
private val mainViewModel: MainViewModel by viewModels()

を記述すれば移行完了です。

3
0
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
0