1. repeatOnLifeCycle 에 대해서 설명해보시오.
lifecycleScope 한계 때문에 해당 메서드를 사용한다.
Flow 를 사용할 때, lifecycleScope 에서 사용하게 된다면, 액티비티가 onDestroy() 될 때는 데이터 collect 가 중단된다.
하지만, 액티비티 종료할 때 호출되는 onDestroy() 메서드가 아니라, 백그라운드로 내려갈 때에는 collect 중단이 되지 않는다.
앱이 백그라운드로 내려가면, 액티비티는 onStop() 이 수행되므로, lifecycleScope 는 계속해서 collect 에서 데이터를 수직한다.
기존에 이 문제를 해결하기 위해선, onStart 에서 collect 를 시작하고, onStop 에서 collect 를 중지하는 작업을 했다.
하지만, 이는 보일러플레이트를 만들어 낸다.
또한, 만약 개발자가 실수로 별도 작업을 하지 않을 경우, 전과 동일하게 불필요하게 데이터 수집이 백그라운드에서 일어날 것이다.
이 상황에 LifecycleScope 내부에서 repeatOnLifeCycle 을 사용해 collect 동작을 최적화할 수 있다.
repeatOnLifeCycle 액티비티가 포그라운드에 있을 때로 한정지어, Lifecycle 이 Trigger가 되었을 대, 동작하도록 만드는 block 이다. 즉, 라이플사이클 범위 내에서 onStop 에서 Job 을 취소하도록 만드는 것이다.
간단히 설명하자면,
repeatOnLifeCycle 은 코루틴 잡이 생성될 Lifecycle.State 를 인자로 받아, 특정 생명주기가 포그라운드에 있을 때까지만 동작하는 코루틴 잡을 생성해주는 메서드이다.
즉, repeatOnLifeCycle 블록 내부에 있는 flow 에 대한 collect 는 액티비티가 포그라운드에 있을 때만 진행하게 된다.
2. Hilt 에서 언급되는 모듈이란?
모듈은 필요한 객체를 제공하는 역할을 한다.
모듈은 클래스 단위로 구성되며, 이 클래스 내에 특정 객체를 반환하는 함수를 정의함으로써
모듈에서 제공하는 객체를 정의할 수 있다.
3. Hilt 에서 언급되는 컴포넌트란?
외부에서 객체를 사용할 때에는 모듈로부터 직접 받는 것이 아니라, 컴포넌트라는 인터페이스를 통하여 객체를 제공 받아야 한다.
즉, 컴포넌트는 외부에서 객체를 제공 받기 위해 사용되는 인터페이스이다.
다시 설명을 해보자.
모듈이 객체를 제공하는 역할을 한다면,
컴포넌트는 모듈에서 제공받은 객체를 조합하여 필요한 곳에 주입하는 역할을 한다.
하나의 컴포넌트는 여러 개의 모듈을 조합할 수 있다.
따라서 목적에 따라 각각 분리된 여러 모듈로부터 필요한 객체를 받아 사용할 수 있다.
만약 모듈을 만들어 컴포넌트를 지정을 하게 된다면,
컴포넌트에 객체를 제공하는 모듈을 지정할 수 있게 됩니다.
4. Hilt 에서 언급한 @Binds 와 @Provides 차이는?
@Binds 는 인터페이스 인스턴스를 제공하는 것
@Provides 는 클래스의 인스턴스(소유하지 않은 클래스)를 제공하는 것이다.
@Binds 를 사용하여, 인터페이스 인스턴스를 제공할 때 실제 사용되는 구현(Interface 를 실제 구현한 클래스)을 Hilt 에 알려준다.
@Provides 는 의존성을 삽입하려는 클래스가 아니라, 외부 라이브러리에 제공되어 클래스를 소유하지 않은 경우나 빌드 패턴 등의 인스턴스를 생성해야하는 경우에 사용된다.
둘의 차이는?
사실 생성자 주입이 가능한 경우에도 @Provides 를 사용할 수 있다.
다만 @Provides 메소드 안에 객체를 만들기만 하기 때문에 굳이 @Provides 를 사용할 이유가 없는 것이다.
따라서, 생성자 주입이 가능한 경우는 @Binds, 객체를 만들 때 복잡한 코드가 필요한 경우 @Provides 를 사용한다고 기억하자.
5. Hilt @SingletonComponent 와 @Singleton 에 대해서 설명하시오.
컴포넌트는 지정된 타입에 맞는 객체를 제공해주는 역할을 가진 클래스이다.
기존 Dagger 와 다르게 Hilt 는 Dagger 컴포넌트를 직접적으로 정의하거나, 인스턴스화할 필요가 없어졌다.
대신에, Hilt 는 이미 정의된 컴포넌트를 통해 생성되는 클래스들을 제공하고 있다.
Hilt 는 안드로이드 애플리케이션의 다양한 생명주기에 자동으로 통합되는 내장 컴포넌트 세트를 해당 스코프 애노테이션과 함께 제공한다.
@SingletonComponent 는 @ApplicationComponent 에서 이름이 변경 됐다.
Injecter 대상이 Application 이고, 애플리케이션 전역에서 사용할 수 있는 컴포넌트를 제공한다.

Hilt 의 각 컴포넌트에 위에 달린 애노테이션은 컴포넌트 바인딩의 생명주기를 지정하는데 사용된다.
각 컴포넌트 아래에 있는 화살표는 하위 컴포넌트를 가르키고 있다.
보통 하위 컴포넌트의 바인딩은 상위 컴포넌트의 바인딩이 가지고 있는 의존성들을 가지고 있다.
@InstallIn(???) 는 모듈 안에 있는 의존성 스코프를 나타낸다. binding 들을 사용할 수 있는 클래스들과 컴포넌트 내의 다른 binding 들을 컨트롤하는데 이용된다.
Hilt 에서 기본적으로 주입 요청이 들어올 때마다, 객체를 binding 에 맞춰서 새롭게 제공한다.
만약 특정 타입의 객체를 Application 전역에서 동일하게 사용하고 싶다면 어떻게 해야할까?
binding 에 @Singleton 애노테이션을 붙히면, Hilt 에게 해당 컴포넌트에게 항상 동일한 객체를 제공하라고 알려줄 수 있다.
💡Scope 란?컴포넌트 외부로부터 객체를 요청 받거나 inject 시점에 모듈에게 객체를 요청하는데, 이 때 모듈은 기본적으로 매 번 새로운 객체를 생성하여 제공하게 된다. 그러나 때로는 객체를 매번 재생성하는 게 좋지 않을 수도 있다. 따라서, @Singleon 애노테이션을 사용한다면 이전에 생성한 동일한 객체를 반환하도록 할 수 있다.
여기서 @Singleton 은 컴포넌트와 연관된 스코프 애노테이션이다.
또한, 각각의 컴포넌트에도 이와 같은 스코프 애노테이션이 존재한다. 위 컴포넌트 계층 그림을 보면 알수 있다.
추가 예시로 만약, 액티비티의 생명주기에 맞춰 특정 객체를 사용하고 싶을 때,
@AcitivityScoped 를 클래스나 binding 에 부착하면 액티비티 생명주기에 맞춰서 한 번만 생성된다.
'Android Q&A > Android One a day' 카테고리의 다른 글
[안드로이드 면접] - : 21 (0) | 2023.02.27 |
---|---|
[안드로이드 면접] - 20 : (0) | 2023.02.24 |
[안드로이드 면접] - 18 : (0) | 2023.02.20 |
[안드로이드 면접] - 17 : (0) | 2023.02.18 |
[안드로이드 면접] - 16 : (1) | 2023.02.17 |