Spring 에서 서비스단의 클래스를 그냥 어노테이션으로 선언만하고 막쓰던것 처럼 DI해주는 Dagger 라는 라이브러리를 기반으로 안드로이드에서 HILT로 새로 내놓았다고함.
Dagger + Android LifeCycle = HILT 라고 생각해도됨.
구글이 Hilt currently supports the following Android classes:
Application
(by using@HiltAndroidApp
)ViewModel
(by using@HiltViewModel
)Activity
Fragment
View
Service
BroadcastReceiver
만 지원한다네.. 뭐 다되는거 아님?
@Inject 어노테이션으로 주입과 사용 양쪽에 사용한다. 사용자가 만든 클래스의 경우에는 Hilt가 삽입하고자 하는 곳에 초기화해서 사용하기 위해서 constructor 에 선언해주면 된다. 다만 안드로이드의 경우 프레임워크이고 라이프사이클이 있어서 Module 고 IntallIn 이라는 어노테이션으로 프레임워크의 어떤 부분에 해당 모듈을 사용할건지를 선언해줘야 한다.
@Module이 클래스에 지정하는 어노테이션이라고 하면, 개개별 메소드에는 @Provide 또는 @Bind를 통해 다른곳에서 Injection하여 끌어다가 사용할수 있도록 한다.
@Provide : 실제 코드를 구현하여 메소드에서 뭔가 작업할때 Object계열읠 클래스일때는 이걸쓴다.
@Bind : Abstract 클래스에서는 메소드도 추상화 시키기 때문에, 실제 구현 코드는
1. 종속성추가
https://developer.android.com/training/dependency-injection/hilt-android?hl=ko
2. Application 클래스를 생성하고 HiltAndroidApp이라고 사용함을 지정, MainActivity에 EntryPoint지정
https://github.com/sugoigroup/android_hilt_example/commit/66e062ae622674d70ed511ab526b95637399aa1b
3.간단하게 사용해보자
https://github.com/sugoigroup/android_hilt_example/commit/84c20d9e6c87108ae378852eb900ca63785278bd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ------------------------------- //사용하고자 하는 클래스 변수에 Inject 를 지정 @Inject lateinit var calcme: CalcMe ... // Inject 지정에 의해 calcme변수에 CalceMe객체가 할동되어있다. Log.e("Test", calcme.sumMe(1, 2).toString()) ------------------------------- //사용하고자 하는 클래스 변수에 Inject 를 지정 class CalcMe @Inject constructor() { fun sumMe(num1:Int, num2:Int) : Int { return num1 + num2 } } |
4.Module 간단한 사용.
https://github.com/sugoigroup/android_hilt_example/commit/112a15def5b62d2203bcfab40462ad3c82559185
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | -------------------------------- MyHiltModule.kt @Module // Module은 클래스에 정의 @InstallIn(ApplicationComponent::class) //Application 의 라이프사이클에 맞추어 동작한다는 의미 class MyHiltModule { @Singleton @Provides // 리턴 타입이 MainApplication 이라면 이게 실행됨. fun provideMeApplication(@ApplicationContext app: Context): MainApplication { // send data to server then receive results return app as MainApplication } @Singleton @Provides // 리턴 타입이 Int형이라면 이게 실행 fun sendAndBringApiService(): Int { // send data to server then receive results return 200 } @Singleton @Provides // 리턴 타입이 String 이라면 이게 실행 fun saveToRepository(): String = "Saved" } -------------------------------- MainActivity.kt //변수에 Inject @Inject lateinit var myapp: MainApplication // MainApplication 을 리턴타입으로 하는 프로바이더 자동 삽입 var resultCode: Int = 0 @Inject set // Int 을 리턴타입으로 하는 프로바이더 자동 삽입 @Inject lateinit var saveRepo: String // Int 을 리턴타입으로 하는 프로바이더 자동 삽입 //출력 Log.v("Test", "my app: ${myapp}") Log.v("Test", "result Code: ${resultCode}") Log.v("Test", "saveRepo result: ${saveRepo}") |
5. 같은 리턴타입의 프로바이더를 Qualifier 로 구분지어 호출하자.
https://github.com/sugoigroup/android_hilt_example/commit/f0df622bdddda5f8bb31db15509569c58774f7f8
-------------------------------- MyHiltModule.kt @Module // Module은 클래스에 정의 @InstallIn(ApplicationComponent::class) //Application 의 라이프사이클에 맞추어 동작한다는 의미 class MyHiltModule { @Singleton @Provides // 리턴 타입이 MainApplication 이라면 이게 실행됨. fun provideMeApplication(@ApplicationContext app: Context): MainApplication { // send data to server then receive results return app as MainApplication } @Singleton @Provides // 리턴 타입이 Int형이라면 이게 실행 fun sendAndBringApiService(): Int { // send data to server then receive results return 200 } @Singleton @Provides @SaveRepoAction // 리턴 타입이 String 이고 @SaveRepoAction 이라면 이게 실행 fun saveToRepository(): String = "delete" @Singleton @Provides @DeleteRepoAction // 리턴 타입이 String 이고 @DeleteARepoction 이라면 이게 실행 fun deleteToRepository(): String = "Saved" } @Qualifier @Retention(AnnotationRetention.RUNTIME) internal annotation class SaveRepoAction @Qualifier @Retention(AnnotationRetention.RUNTIME) internal annotation class DeleteRepoAction } -------------------------------- MainActivity.kt //변수에 Inject @Inject @SaveRepoAction lateinit var saveRepo: String // Int 을 리턴타입으로 하는 프로바이더 자동 삽입 @Inject @DeleteRepoAction lateinit var deleteRepo: String // Int 을 리턴타입으로 하는 프로바이더 자동 삽입 //출력 Log.v("Test", "deleteRepo result: ${deleteRepo}") Log.v("Test", "saveRepo result: ${saveRepo}")
6. @bind로 사용자가 정의한 constructor를 써보자.
https://github.com/sugoigroup/android_hilt_example/commit/dfcd4f7e3b96efb2fa3274b98611665d2dd6e9c5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | -------------------------------- MyHitAbs.kt @Module @InstallIn(ApplicationComponent::class) abstract class MyHiltAbs{ //추상클래스를 모듈로 선언 @Singleton @Binds //PowerInterfaceImpl 을 powerImpl에 Inject하고, PowerInterface형식을 선언하는 곳에 구현제를 바인드 해준다. abstract fun bindMyComputer(powerImpl: PowerInterfaceImpl): PowerInterface } interface PowerInterface { fun getPower(): String } class PowerInterfaceImpl @Inject constructor(): PowerInterface { override fun getPower(): String { return "Low Power(<220)" } } // Binds에 의해 자동으로 powerImpl 변수는 PowerInterfaceImpl 구현체에 바인드 되어 진다. class MyComputer @Inject constructor(private val powerImpl: PowerInterface) { fun powerStart(): String { return "${powerImpl.getPower()}" //구현체의 getPower가 실행된다. } } -------------------------------- MainActivity.kt @Inject lateinit var myComputerBinded: MyComputer; //Inject와 동시에 Bind에 지정된 구현체가 연결된다. Log.v("Test", "bind example: ${myComputerBinded.powerStart()}") |
이밖에 ViewModel과의 연동도 가능한다.
저렇게 써놓으면 Hilt가 언제 내 소스에 관련 Injection 소스들을 쑤셔넣어주냐 하면,
구성요소 전체 기간
Hilt는 해당 Android 클래스의 수명 주기에 따라 생성된 구성요소 클래스의 인스턴스를 자동으로 만들고 제거합니다.
생성된 구성요소 | 생성 위치 | 제거 위치 |
---|---|---|
ApplicationComponent | Application#onCreate() | Application#onDestroy() |
ActivityRetainedComponent | Activity#onCreate() | Activity#onDestroy() |
ActivityComponent | Activity#onCreate() | Activity#onDestroy() |
FragmentComponent | Fragment#onAttach() | Fragment#onDestroy() |
ViewComponent | View#super() | 제거된 뷰 |
ViewWithFragmentComponent | View#super() | 제거된 뷰 |
ServiceComponent | Service#onCreate() | Service#onDestroy() |
구글 공식사이트에서 이렇다고 한다.
참고
제일 자세한 한글 :https://hyperconnect.github.io/2020/07/28/android-dagger-hilt.html
dagger2가 궁금하다면 여기 : http://pluu.github.io/blog/android/2017/01/12/android-dagger/
0 comments:
댓글 쓰기