내가 힐트 공부한 방식과 코드랩 진행하면서 봤던 용어를 정리해두려고 한다.
코드랩까지 해보니,
가장 기본적 내용만 본거지만, 어렵다 할 내용은 아닌듯하다.
하지만 이걸 학습하는데 굉장히 무섭게 다가왔는데
용어가 낯설어서 그런것 같다.
힐트랑, 대거 라이브러리 이름자체는 굉장히 잘 지은것 같은데,,
실제 써보려하니 뭔가 파일이 쪼개져서 그런지 계속 헷갈리고 용어도 모르겠다.
이게 다.. 구글 선생님들도 헷갈리니 제대로 못가르치는거라고 생각하고 위안을 삼아야겠다.
계속해서 써보면 익숙해질듯하다.
// 힐트 공부를 어떻게 했나?
-> 구글공식문서 읽고, 구글 코드랩 진행
1) 구글문서 링크 (구글 문서는 한국어로 보면 옛날 자료일수도 있으므로, English로 두고 한국어와 비교해봐야한다.)
https://developer.android.com/training/dependency-injection
목차중에서 Dependency injection 개요, 수동으로 주입, 힐트로 디펜던시,...
힐트관련 문서를 읽는다.
이 문서를 따라하기보다는, 코드랩에서 어차피 다 돌려볼테니 코드 스니펫정도만 이해하면 될듯하다.
문서 읽는 것만 하루는 꼬박 걸리는것 같다.
구글 문서는 보면 바로 이해가 안된다.
공식 문서는 항상 어느정도만 대충 읽고, 실제 예제를 돌리면서 이해 해야한다.
2) 구글 hilt 코드랩 링크
https://developer.android.com/codelabs/android-hilt
코드랩도, 한국어로 보면 문서가 옛날거일수 있다.
English로 해놓고 한국어 번역을 하던지,
English와 한국어 둘다 띄우고 비교해서 보던지 해야한다.
구글 문서읽을때는 힐트-모듈쪽부터는 이해가 잘안되었지만,
확실히 코드랩을 따라해보면, 좀 더 이해가 되는듯 하다.
// 용어 정리
내가 이해한 내용을 정리했으므로, 용어가 틀릴 수도 있음.
// Container
서비스 로케이터 패턴처럼, 쓰려는 객체들 따로 담아두는 것
바인딩해둔 클래스(컴포넌트), 그리고 모듈도 컨테이너라 보는듯하다.
// @HiltAndroidApp
application 클래스에서 작성하는 어노테이션
힐트 코드가 생성되는것을 트리거함.
application container를 생성한다는듯함.
이게 다른 컨테이너들의 최상위가 되는.
// @AndroidEntryPoint
안드로이드 클래스 라이프 사이클을 따르는
'dependencies container'를 생성한다.
다음과 같은 안드로이드 타입만 사용가능.
Application (by using @HiltAndroidApp), Activity, Fragment, View, Service and BroadcastReceiver.
힐트는,
FragmentActivity, AppcompatActivity, jectpack의 Fragment만 사용되고,
안드로이드의 fragment는 또 지원하지 않는다고함.?
// @Inject
field injection(필드 인젝션), constructor injection(생성자 인젝션)에서 씀.
- 필드 인젝션에서는 @Inject는
해당 필드를 내가 따로 인스턴스화를 안해도 되고, 이 어노테이션을 작성하면 객체가 생성됨.
그리고 해당 필드는 private가 되어서는 안된다.
- 생성자 인젝션에서 @Inject는
필드인젝션에서 쓰려는 애가 어디서 만들어지는건지
생성자부분에 알려줘야함.
(바인딩 되는부분이 뭔지 알리는역할?)
// binding (바인딩, 결합)
필드 인젝션을 하려면 어떻게 들고오는건지 알려줘야하는데,
-> 클래스정의 된 곳에서, 생성자에 @inject를 붙이게 된다.
바인딩해둔(생성자 인젝션해둔) 클래스를 대충 Component(컴포넌트)라 부르는것 같다?
이 바인딩한다는게 그냥 constructor injection을 하고 나서,
바인딩 되는것이지 constructor injection 그 자체를 뜻하는것은 아닌듯한데..
// scoping an instance to a container.
컨테이너에 인스턴스 스코프를 지정
서비스 로케이터에서 항상 같은 인스턴스를 반환하는것(싱글톤을)을 힐트로도 만드려함.
Component scope (컴포넌트 스코프)
바인딩한 클래스에다가
@Singleton으로 어노테이션.
compoent scope로 바인딩된 컴포넌트가,
component hierarchy에 따라서 다른 컨테이너에서도 사용할 수 있게 된다는듯?
// transitive dependencies (전이 종속성)
(컴포넌트) -> (컨슈머)?
a -> b -> c
a와 b사이에 종속성이 있다.
a와 c사이에는 전이 종속성이 있다.
// Hilt modules
또 바인딩을 해야하는게 있는데,
interface는 생성자가 없어서 @inject를 사용할 수 없다.
또는 다른곳에서 인스턴스를 하는 빌드 패턴같은거.
이런 경우 어떻게 해결하나?
-> 힐트 모듈을 만들어야한다.
@Module
이거는 모듈이라고 알린다.
@InstallIn
이 구체화 되는 컴포넌트가 어디에서 바인딩이 가능한지를 힐트에 알린다.
힐트 컴포넌트는 컨테이너로서 생각할 수 있다.
안드로이드 클래스들도 힐트로 주입될 수 있다.
모듈내부에는 두가지 방법으로
@Provide와 @Binds를 쓴다.
@Provide
모듈은 object클래스가 될 수 있다.
(이 object클래스에서 함수를 구현)
(이게 빌드 패턴같은거에서 쓰는거인듯)
생성자 주입을 쓰지 못하는 것들에 대해서
@Provide를 달아서 어떻게 제공되는건지 알린다.
@Binds
힐트 모듈 내부에서
인터페이스 구현체거나 abstract함수에는 를 달아줘야한다.
// Qualifiers (한정자)
인터페이스 구현중..
같은 타입인데
다른 scope로 작동되어야하는 경우.
같은 파일에 모듈을 따로 만들고,
이름 다른 추상 함수를 2개만든다.
근데 이렇게 두개 만들면,
필드 주입하는곳에서 뭘 가져다 써야할지 모르기 때문에
@Qualifiers 어노테이션으로 -> 커스텀 어노테이션을 만들고
@Binds하는 함수에, 커스텀 어노테이션을 달아준다.
필드 주입하는 곳에서도, 사용할 커스텀 어노테이션을 달아서 바인딩을 완성하면된다.
// Test
힐트를 사용하여
ui test시,
gradle.build(app) - dufaltConfig에 testInstrumentationRunner를 커스텀으로 따로지정해야한다.
이 runner를 따로 지정한다는 옵션이 뭔지는 정확하게 모르겠는데, 힐트를 사용한다고 알려주는거 같다.
여튼 CustomTestRunner 클래스를 따로 만들어서,
AndroidJUnitRunner를 extends하고
return에 className을 HiltTestAppication::class.java.name으로 변경해줘야함.
// @EntryPoint
일반적인 안드로이드 컴포넌트가 아닌, (ex. ContentProvider)
힐트를 사용할 수 없는 클래스에서
힐트를 사용하려고 할때,
@EntryPoint가 그 주입의 시작점이 되는 지점이라고 함.
@AndroidEntryPoint를 사용할 수없을 경우에,
인터페이스를 생성하여 @EntryPoint를 작성해야함.
또한, 그 생성한 인터페이스는 @InstallIn을 같이 작성해야한다.
그리고 그 인터페이스를
EntryPointAccessors로 액세스해야하는데,
이때, EntryPointAccessors 파라미터가 컴포넌트 인스턴스 or @AndroidEntryPoint객체가 되야한다고하는데 무슨말인지 잘 모르겠다.
그리고 그 파라미터들과 EntryPointAccessors statc메서드가
인터페이스에서 작성했던 @Installn과 일치해야한다고 함.
expose한다는 말이있다.
-> 이렇게 EntryPoint를 만들어서 힐트에서 시작점이 어딘지 노출된다는 말인듯.
// 안드로이드 스튜디오에서 에디터에서 나타나는 아이콘 모양에 대한 설명.
(구글 di문서 개요 그림2을 거꾸로 놔둔모양인거 같다.)
의미 -> 이것은 Cunsumer, di로 인스턴스 된 것을 사용한 부분이다. (Field가 di한 Type의 인스턴스를 cunsume한다, 혹은 expose한다)
누르면 -> 어디서 bind되었는지 나옴. (컴포넌트, 생성자 inject된 부분)
의미 -> 이것은 컴포넌트다 (이것은 ~을 위해 제공된다, provide한다, ~과 관련이 있다. exposed된다.)
누르면 -> 어디서 참조하고 있는지 나옴.
저 두 아이콘이 동시에 있는것도 있으니,
cunsumer이면서, 동시에 component가 되는것으로 알아서 잘 이해하면 될 듯하다.
// 결론
이렇게 정리를 해도 잘모르겠는데,
역시 써보면서 익혀야 할 내용인거 같다.
scope부분은 아직도 감은 안온다.
나중에 dagger, koin같은거를 공부하게 되면, 이해가 더 잘 될지도?
이제 mvvm패턴을 공부할 차례가 점점 다가온다..
'Android > Kotlin in android' 카테고리의 다른 글
안드로이드 버튼 android:src와 app:srcCompat 두 속성의 차이점 (with. chatgpt) (0) | 2024.02.23 |
---|---|
android android:gravity와 android:layout_gravity의 차이 (0) | 2023.08.25 |
RecyclerView를 연습해보았다 (공부한 자료 & 회고) (0) | 2023.04.28 |
코루틴coroutine &플로우flow 학습 했던거 회고 (0) | 2023.04.25 |
뷰 바인딩 (View Binding) (0) | 2022.10.27 |