안드로이드 앱 코드가 마치 뜨거운 감자처럼 클래스 간에 인스턴스가 이리저리 넘겨지면서 완전히 엉망이 되어가는 것처럼 느껴진 적이 있다면, 아마도 다음과 같은 함정에 빠졌을 가능성이 큽니다... 의존성의 지옥프로젝트가 관리하기 어려워지는 것을 방지하기 위해 Google은 Dagger Hilt라는 도구를 도입했습니다. 이 도구는 모든 복잡한 작업을 처리하여 클래스에 필요한 객체를 자동으로 생성해 주기 때문에, 개발자가 똑같은 코드를 반복해서 작성하는 데 지칠 때까지 기다릴 필요가 없습니다.
다소 복잡한 학습 곡선으로 인해 부담스러울 수 있는 기존 Dagger와 달리, Hilt는 훨씬 더 표준화되고 직관적인 접근 방식을 제공합니다. Hilt는 다음과 같은 기능과 훌륭하게 호환됩니다. 젯팩 컴포즈와 현대 건축컴파일 중에 모든 것이 검증되므로 런타임 성능이 최적화되고 종속성 오류로 인한 예상치 못한 문제가 발생하지 않습니다.
초기 구성 및 시스템 시작
Hilt를 사용하려면 먼저 Gradle 파일에서 환경을 설정해야 합니다. 루트 파일에 hilt-android-gradle-plugin을 추가하고 애플리케이션 모듈에 필요한 종속성을 적용하는 것이 중요합니다. 여기서 핵심은 프로젝트가 다음과 같이 구성되어야 한다는 것입니다. 자바 17그렇지 않으면 Hilt와 Compose의 현재 버전은 상당한 골칫거리가 될 수 있습니다.
이 시스템이 제대로 작동하려면, 이 시스템을 사용하려는 모든 앱은 `Application` 클래스에 `@Application` 어노테이션이 표시되어 있어야 합니다. @HiltAndroidApp이 레이블은 코드 생성을 활성화하고 전체 객체 그래프가 위치할 기반을 만드는 스위치입니다. 이 레이블이 없으면 Hilt는 고정될 곳이 없어 어떤 작업도 작동하지 않습니다.
안드로이드 컴포넌트에 종속성 주입하기
기본 설정이 완료되면 Hilt에게 어떤 클래스로 객체를 받을지 알려줘야 합니다. 이를 위해 다음 명령어를 사용합니다. @안드로이드엔트리포인트이 기능은 액티비티, 서비스, 브로드캐스트리시버 등 프레임워크의 대부분 요소와 호환됩니다. Compose를 사용하는 경우 루트 액티비티에 어노테이션을 추가하기만 하면 모든 구성 가능한 요소가 주입된 ViewModel에 문제없이 접근할 수 있습니다.
액티비티 코드에 객체를 직접 삽입하려면 필드 주입을 사용합니다. @Inject변수를 `lateinit var`로 정의하고 어노테이션을 추가하기만 하면 됩니다. 하지만 주입된 필드에 대해서는 매우 주의해야 합니다. 그것들은 비공개일 수 없습니다.Hilt가 인스턴스를 할당하기 위해 해당 변수에 접근해야 하기 때문입니다. 만약 해당 변수를 private으로 설정하려고 하면 컴파일러가 즉시 오류를 발생시킬 것입니다.
연결 기술: @Binds와 @Provides의 차이점
Hilt는 우리가 요청하는 모든 것을 생성하는 방법을 알아야 합니다. 가장 간단한 방법은 생성자 주입으로, 클래스 생성자에 `@Inject` 어노테이션을 붙이는 것입니다. 하지만 특정 상황에서는 이것이 불가능할 수 있습니다. 예를 들어 다음과 같은 경우입니다. 외부 인터페이스 또는 라이브러리 소스 코드를 수정하여 주석을 추가할 수 없는 개조 또는 룸 유형입니다.
여기서 모듈이 등장하는데, 모듈은 `@Module` 및 `@InstallIn` 어노테이션이 붙은 클래스입니다. 인터페이스를 구체적인 구현체에 연결하려면 가장 효율적인 방법은 모듈을 사용하는 것입니다. @바인즈추상 함수는 매개변수로 구현체를 받고 반환값으로 인터페이스를 받는 형태로 정의됩니다. 기본적으로 Hilt에게 "누군가 AnalyticsService를 원할 때 AnalyticsServiceImpl을 제공하라"고 알려주는 것입니다.
반면에 객체 생성에 더 복잡한 논리가 필요하거나 제3자에 의해 생성되는 경우에는 다른 방법을 사용합니다. @제공합니다여기서는 Retrofit 클라이언트의 기본 URL을 구성할 때처럼 인스턴스가 어떻게 구성되는지를 본문에 자세히 설명하는 일반 함수를 작성합니다. 간단히 말해, `@Binds`는 위임에 사용되고, `@Provides`는 객체 생성에 사용됩니다. 종속성을 수동으로 생성합니다.
@Qualifier를 사용한 충돌 관리
때로는 동일한 객체 유형의 두 가지 다른 버전이 필요할 때가 있습니다. 예를 들어, 인증이 필요한 호출용 OkHttpClient 클라이언트와 일반 공개 요청용 OkHttpClient 클라이언트가 두 개 있다고 가정해 보겠습니다. 추가 설정 없이 두 클라이언트를 모두 주입하려고 하면 Hilt는 어떤 클라이언트를 선택해야 할지 몰라 패닉에 빠집니다. 이 문제를 해결하기 위해 다음과 같은 방법을 사용합니다... 사용자 지정 한정자.
한정자는 기본적으로 자체 주석으로 표시됩니다. @Qualifier우리는 `@AuthInterceptorOkHttpClient`와 같은 태그를 생성하고, 인스턴스를 제공하는 모듈 메서드와 인스턴스를 주입하는 메서드 모두에 해당 태그를 배치합니다. 이렇게 하면 Hilt는 오류 없이 동일한 유형의 바인딩을 구분할 수 있습니다. 또한, 다음과 같은 매우 유용한 사전 구축된 한정자도 있습니다. @ApplicationContext 및 @ActivityContext이를 통해 우리는 원하는 결과를 얻기 위해 자체 모듈을 만들 필요가 없습니다. 안드로이드 컨텍스트.
생명주기 동기화 및 범위 설정
기본적으로 Hilt는 종속성이 요청될 때마다 새 인스턴스를 생성합니다. 하지만 컴포넌트의 수명 주기 동안 객체가 동일하게 유지되어야 하는 경우가 있습니다. 이를 위해 다음과 같은 기능을 제공합니다... 범위클래스에 @Singleton 어노테이션을 붙이고 SingletonComponent에 설치하면 애플리케이션 전체에서 공유되는 단일 인스턴스를 갖게 됩니다.
더 세부적인 단계들도 있습니다. 예를 들어, @ActivityScoped `@ViewModelScoped`는 액티비티의 수명 주기 동안 동일한 인스턴스가 사용되도록 보장하며, `@ViewModelScoped`는 뷰모델에도 동일하게 적용되어 화면 회전 시 종속성이 다시 생성되는 것을 방지합니다. 하지만 객체를 메모리에 너무 오래 유지하면 문제가 발생할 수 있으므로 스코프를 과도하게 사용하는 것은 권장되지 않습니다. 성능을 저하하다 그리고 안드로이드 메모리 관리.
특별한 경우: @EntryPoint 및 지원되지 않는 클래스
Hilt는 매우 강력하지만 모든 곳에 적용되는 것은 아닙니다. ContentProvider와 같은 시스템 클래스는 @AndroidEntryPoint를 지원하지 않습니다. 이러한 경우에는 Hilt를 사용하여 진입점을 생성하는 것이 해결책입니다. @EntryPoint이는 Hilt에서 관리하는 코드와 외부 코드 사이의 연결 고리 역할을 하는 인터페이스를 정의합니다.
이 다리에서 시설을 복구하기 위해 우리는 다음을 사용했습니다. 엔트리포인트액세서리우리는 적절한 컨텍스트와 EntryPoint 인터페이스를 전달합니다. 이를 통해 자동 주입이 도달할 수 없는 영역에서도 Hilt 그래프로부터 종속성을 수동으로 추출할 수 있습니다.
손잡이와 단검의 차이점
Hilt는 Dagger를 대체하는 것이 아니라 Dagger를 기반으로 구축되었습니다. Hilt의 가장 큰 장점은 컴포넌트를 직접 작성하고 그 수명 주기를 관리할 필요가 없다는 것입니다. 컨테이너를 자동으로 생성합니다. 안드로이드 클래스와 연결되어 있습니다. 이렇게 하면 반복적인 코드가 크게 줄어들고 프로젝트의 가독성이 훨씬 좋아집니다.
이 시스템 덕분에 제어권의 역전이 자연스러운 과정이 됩니다. 클래스는 필요한 것을 알려주고, Hilt는 그것을 제공하는 역할을 합니다. 이는 일상적인 개발을 간소화할 뿐만 아니라 여러모로 이점이 많습니다. 단위 테스트실제 구현체를 테스트 더블로 대체할 수 있고, 비즈니스 로직은 건드리지 않아도 되기 때문입니다.
Android에서 Hilt를 구현하면 강력하고 효율적인 의존성 관리가 가능해져 중복 코드를 제거하고 확장 가능한 애플리케이션 개발을 용이하게 합니다. Hilt의 정확한 사용 덕분에 이러한 이점이 가능해집니다. @Binds, @Provides 및 @Qualifier개발자는 타입 충돌을 해결하고 객체 수명 주기를 세밀하게 관리할 수 있으므로 제어의 역전을 통해 애플리케이션의 유지 관리성과 테스트 용이성을 보장할 수 있습니다.