Hilt 란?
Hilt는 기존 Dagger2를 보일러 플레이트 코드를 제거하기 위해 안드로이드의 구조에 맞춰 몇 가지 Annotaion을 추가한 라이브러리이다.
안드로이드 11 프리뷰에서 Hilt 를 공식적으로 Jetpack에 합류시킨다고 발표했다.
간단한 예제와 함께 살펴보자.
1. 시작하기
/-- build.gradel(project) --/
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.28-alpha'
-------------------------------------------------------------------------------
/-- build.gradel(app) --/
apply plugin: 'dagger.hilt.android.plugin'
dependencies {
implementation "com.google.dagger:hilt-android:2.28-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
//viewModel 관련된 확장 라이브러리
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
}
현재는 Alpha 버전으로 추후 변경될 여지가 있다.
2. Application 설정
@HiltAndroidApp
class ToDoApplication : Application()
@HiltAndroidApp
로 가능
Dagger2는 DaggerApplication
를 상속받아서 Application을 만들고 모듈을 제공하기 위해 AndroidInjector<DaggerApplication>
도 상속받아 구현해야 했다.
Hilt에서는 @InstallIn(ApplicationComponent::class)
코드를 Module에 붙이면 앱에서 해당 모듈을 제공할 수 있다.
context, application을 제공하기 위한 ApplicationContextModule 또한 미리 정의되어 있다.
3. Activity, Fragment 그리고 뷰 모델
@AndroidEntryPoint
class ToDoActivity : AppCompatActivity() {
private val toDoViewModel: ToDoViewModel by viewModels ()
...
}
@AndroidEntryPoint
로 가능
Dagger2에서 DaggerActivity
, DaggerFragment
등을 상속받는 코드를 간단한 Annotation으로 대체하였다.
현재는 Activity
, Fragment
, View
, Service,
BroadcastReceiver
에 대해서만 지원한다.
그 외에 클래스에 대한 주입은 @AndroidEntryPoint
을 통해서 할 수 없다. ( 사실 저거면 충분한 거 같다.. )
class ToDoViewModel @ViewModelInject constructor(
private val toDoRepository: ToDoRepository,
@Assisted private val savedStateHandle: SavedStateHandle) : ViewModel() {
...
}
@ViewModelInject
로 가능 , 확장 라이브러리에 포함되어 있다.
Dagger2 에서는 ViewModelStoreOwner를 지정해주기 위해서 ViewModel 이 아닌 ViewModelFactory에 주입을 하여 사용했다.
Hilt의 @ViewModelInject
를 사용하면 기존 방법대로 뷰모델을 생성만 해도 주입된 뷰 모델을 가져올 수 있수 있도록ViewModelFactoryModules 로 정의 해놓았다.
또한 @Assisted
annotation을 붙이면 SavedStateHandle
를 주입해준다.
4. Module
@Module
@InstallIn(ApplicationComponent::class)
class RoomModule {
@Provides
@Singleton
fun provideAppDatabase(@ApplicationContext context: Context): ToDoDatabase {
return Room.databaseBuilder(context,
ToDoDatabase::class.java, "todo_database")
.fallbackToDestructiveMigration()
.allowMainThreadQueries()
.build()
}
@Provides
@Singleton
fun provide(appDatabase: ToDoDatabase): ToDoDao {
return appDatabase.toDoDao()
}
}
@Module
@InstallIn(ApplicationComponent::class)
class RepositoryModule {
@Binds
@Singleton
fun getToDoRepository(toDoRepo: ToDoRepositoryImpl): ToDoRepository
}
@Singleton
class ToDoRepositoryImpl @Inject constructor(private val toDoDao: ToDoDao) : ToDoRepository {
...
}
모듈은 기존 Dagger2와 동일하게 작성한 후 @InstallIn(ApplicationComponent::class)
를 통해 @Component
를 따로 만들지 않고도 컴포넌트에 추가할 수 있다.
ApplicationComponent 외에도 ActivityRetainedComponent, ActivityComponent, FragmentComponent, ViewComponent , ViewWithFragmentComponent, ServiceComponent을 Hilt에서 미리 정의해 놓았다.
ApplicationContextModule에서 제공하는 context를 주입받으려면 @ApplicationContext
를 사용하면 된다.
5. 마무리
Dagger2에서 작성해야 하는 코드의 양 ( 얼마 안 해봤지만.. ) 이 Hilt에서 확실하게 줄어든 느낌이다.
위에 나온 몇 개의 annotation 정도면 기본적인 앱을 만들기엔 충분해 보인다.
'안드로이드' 카테고리의 다른 글
[And] navigation #1 - 기본 사용법 (1) | 2020.06.18 |
---|---|
안드로이드 paging 3.0 #2 - LoadState (0) | 2020.06.16 |
안드로이드 Paging 3.0 #1 - 맛보기 (5) | 2020.06.13 |
Android 에서 미리보기 ( Open Graph ) 만들기 (1) | 2020.03.03 |
Android 에서 Firebase Test Lab 로그인 하기 (0) | 2020.03.03 |