DI(依存性注入)をHiltで追加してみます
今回もごちゃごちゃやらず最低限必要なところだけサクッと実装です
アノテーションチートシート
https://developer.android.com/images/training/dependency-injection/hilt-annotations.pdf
com.google.dagger:hiltの場合
developerの説明は以下
https://developer.android.com/training/dependency-injection/hilt-android?hl=ja
依存関係の設定
以下をProject Structureなどでimplementationします
com.google.dagger:hilt-android
com.google.dagger:hilt-android-compiler
またhiltViewModel()を使用するため以下もimplementationします
androidx.hilt:hilt-navigation-compose (1.1.0-alpha01以降)
lib.versions.tomlの修正もしときます
[versions]
hilt = "2.48"
[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" }
[plugins]
com-google-dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
build.gradleの設定
kaptの設定をします
kotlin(“kapt”)の設定設定を入力したらいったんSyncして有効にしてからkapt設定してください
ksp対応は現在α版のようです
https://dagger.dev/dev-guide/ksp.html
plugins {
alias(libs.plugins.com.google.dagger.hilt.android) apply false
}
plugins {
kotlin("kapt")
alias(libs.plugins.com.google.dagger.hilt.android)
}
kapt {
correctErrorTypes = true
}
dependencies {
implementation(libs.hilt.android)
kapt(libs.hilt.compiler)
}
Applicationクラスの追加
@HiltAndroidAppアノテーションをつけたApplicationクラスの追加します
/**
* ```AndroidManifest.xml
* <application
* android:name=".Application"
* ```
*/
@HiltAndroidApp
class Application : android.app.Application() {
override fun onCreate() {
super.onCreate()
}
}
Activityの設定
Activityに@AndroidEntryPointアノテーションをつけます
これで準備完了です
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
...
}
実装
とりあえず最小構成と思われる実装
以前紹介したContenerの変わりにModuleを追加する感じです
ビルド成功すると自動生成されたJavaのコードができるので確認してみてください
interface Repository {
fun test()
}
class DefaultRepository @Inject constructor() : Repository {
override fun test() {
Log.d("App", "test")
}
}
// シングルトンの場合object
@Module
@InstallIn(ViewModelComponent::class)
object RepositoryBindModule {
@Provides
fun defaultRepository(): Repository {
return DefaultRepository()
}
}
// または以下の実装
/*
@Module
@InstallIn(ViewModelComponent::class)
abstract class RepositoryBindModule {
@Singleton
@Binds
abstract fun defaultRepository(repo: DefaultRepository): Repository
}
*/
@HiltViewModel
class MainViewModel @Inject constructor(
private val repo: DefaultRepository
) : ViewModel() {
fun test() {
repo.test()
}
}
@Composable
fun AppScreen(
modifier: Modifier = Modifier,
viewModel: MainViewModel = hiltViewModel(),
) {
LaunchedEffect(Unit) {
viewModel.test()
}
//...
}
androidx.hiltの場合
※ @Binds / @Providesあたりがcom.google.daggerのHiltと同じ実装だと正しく動作してないようでandroidx版の実装方法のサンプルも無く現時点では使い方がわかりません…とりあえず動作できたところまでです
jetpack版の開発も着々と進んでいるようですが、まだ開発段階なのでJetpack Compose環境のDIは手動が良さそう
developerの説明は以下
https://developer.android.com/training/dependency-injection/hilt-jetpack
https://developer.android.com/jetpack/androidx/releases/hilt
依存関係追加
以下をProject Structureなどでimplementationします
androidx.hilt:hilt-common
androidx.hilt:hilt-compiler
またhiltViewModel()を使用するため以下もimplementationします
androidx.hilt:hilt-navigation-compose (1.1.0-alpha01以降)
またkspにも対応しているのでkspの設定も追加します
[versions]
hilt = "1.1.0-alpha01"
com-google-devtools-ksp = "1.9.0-1.0.13"
[libraries]
androidx-hilt-common = { group = "androidx.hilt", name = "hilt-common", version.ref = "androidx-hilt" }
androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "androidx-hilt" }
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version = "1.1.0-alpha01" }
[plugins]
com-google-devtools-ksp = {id = "com.google.devtools.ksp", version.ref = "com-google-devtools-ksp" }
build.gradleの設定
plugins {
alias(libs.plugins.com.google.devtools.ksp) apply false
}
plugins {
alias(libs.plugins.com.google.devtools.ksp)
}
dependencies {
implementation(libs.androidx.hilt.common)
ksp(libs.androidx.hilt.compiler)
implementation(libs.androidx.hilt.navigation.compose)
}
実装
/**
* ```AndroidManifest.xml
* <application
* android:name=".Application"
* ```
*/
@HiltAndroidApp
class Application : android.app.Application() {
override fun onCreate() {
super.onCreate()
}
}
@HiltViewModel
class MainViewModel @Inject constructor() : ViewModel() {
fun test() {
Log.d("App", "test")
}
}
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ComponentActivity.viewModelsでも取得できる
val viewModel: MainViewModel by viewModels()
viewModel.test()
...
}
@Composable
fun AppScreen(
modifier: Modifier = Modifier,
viewModel: MainViewModel = hiltViewModel()
){
LaunchedEffect(Unit) {
viewModel.test()
}
}
Android Studio Giraffe 2022.3.1 Patch 1 built on August 17, 2023