728x90

[현상]

개인프로젝트 중 힐트 어노테이션 의존성(?)을 추가하니 빌드에러가 난다..... 

    ksp(libs.hilt.android.compiler)

 

[원인]

KSP 는 아직 힐트를 지원하지 않음

 

https://issuetracker.google.com/issues/179057202

 

Google Issue Tracker

 

issuetracker.google.com

 

증말 너무한다잉

 

 

[해결]

kapt 로 돌아가야한다 뿌엥...

 

Before

plugins {
	// ...
    id("com.google.devtools.ksp")
}

dependencies {
	// ...
        ksp(libs.hilt.android.compiler)
}

 

After

plugins {
	// ...
    kotlin("kapt")
}

dependencies {
	// ...
        kapt(libs.hilt.android.compiler)
}

 

혹시 추가 설명이 필요하신 분은 아래 링크 참고 

 

https://kotlinlang.org/docs/kapt.html#annotation-processor-arguments

 

kapt compiler plugin | Kotlin

 

kotlinlang.org

 

그렇게... 나의 빌드속도 향상이여...안녕히... 

android dev 의 'Migrate from kapt to KSP' 문서에서 발췌..

 

모듈화가 되어있기는 하나 Hilt 는 뭐 거의 다 쓰이기때문에.....하..... 

그냥 업뎃을 기다려야겠다

 

그래서 프로덕션에서는 maintenance 상태인 kapt 를 쓰는구나....ㅎ

728x90
728x90

Hilt 를 이용한 DI에서,

구현체를 만들 때 3가지 어노테이션을 사용할 수 있다.

 

간단히 플로우차트로 나타내면 아래와 같다.

 

 

 

가장 간단한 케이스로, constructor 가 존재하여

1. 모듈이 필요없는 의존성 주입

@Inject constructor(param….) 

class DateFormatter @Inject constructor() {

    @SuppressLint("SimpleDateFormat")
    private val formatter = SimpleDateFormat("d MMM yyyy HH:mm:ss")

    fun formatDate(timestamp: Long): String {
        return formatter.format(Date(timestamp))
    }
}

위 코드는 구글의 Hilt codelab Solution에서 가져왔다.

 

2. 모듈이 필요한 의존성 주입 (constructor 없음)

 

Constructor가 없는 이유에 따라 해결법이 갈린다.

a. 외부라이브러리임, 빌더패턴임

b. Interface 임

 

@Module, @InstallIn(...) 의 어노테이션이 있는 

모듈 클래스 내부에 @Provides, @Binds 어노테이션이 붙은 함수를 이용한다.

주의 - 둘은 섞어서 쓸 수 없음...

 

2-a. @Provides 어노테이션

외부라이브러리나 빌더패턴의 경우에 사용

코드랩 솔루션 일부 (ApplicationComponent 는 현재 Deprecated -> Delete 되었으나 이 글은 @Provides 를 설명하는 글이지 scope를 설명하는 글이 아니고, 코드랩에는 아직 이게 나와있어서 그냥 복붙,,, 이제 쓸일없는 코드)

@InstallIn(ApplicationComponent::class)
@Module
object DatabaseModule {

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext appContext: Context): AppDatabase {
        return Room.databaseBuilder(
            appContext,
            AppDatabase::class.java,
            "logging.db"
        ).build()
    }
    //...
}

 

 

2-b. @Binds 어노테이션

 

인터페이스를 주입할 때 필요한 정보를 제공하는 역할.

추상함수 형태로 제공 (따라서 이것을 포함하는 Module class역시 추상 class 가 된다.) -> Binds 와 Provides 를 섞어쓸 수 없는 이유

역할 : 인터페이스클래스와 구현체 클래스를 알려줌 

  • 리턴타입 : 어떤 인터페이스 인스턴스를 제공하는지 알려줌
  • 파라미터 타입 : 인터페이스를 상속하는 녀석들중에 어떤 구현체를 제공할지 Hilt 에 알려줌

 

@InstallIn(ActivityComponent::class)
@Module
abstract class LoggingInMemoryModule{

    @ActivityScoped
    @Binds
    abstract fun bindInMemoryLogger(impl: LoggerInMemoryDataSource) : LoggerDataSource
}


아마도 함수가 사용안됨으로 표시될건데

@Inject 하면 그렇게 표시되더라도 Inject 하는 곳으로 안내됨..(?) 즉, 신경쓸필요없음

 

 

위의 세 방식으로 힐트에게 의존성 주입 방법에 대해 알려주었다.

 

Binds 나 Provides 는 같은 인터페이스/클래스에 대해 각기 다른 구현을 여러개 가질 수 있다.

이렇게 여러 구현이 있는 경우 @Qualifier 로 어떤 구현을 사용할지 구분할 수 있다.

 

 

나도 힐트 초보자이고, 사용법 가이드라기보다는 개념을 이해하기위해 쓴 글이기때문에 엄밀하지 않은 부분이 있을 수 있다.

틀린부분을 댓글로 달아주시면 감사감사... 

 

더보기
728x90
728x90

Hilt codelab 을 진행하다가 위와같은 오류를 만났다

error: cannot find symbol @dagger.hilt.InstallIn(value = {ApplicationComponent.class})

https://developer.android.com/codelabs/android-hilt?hl=ko#6 

 

Android 앱에서 Hilt 사용  |  Android 개발자  |  Android Developers

이 Codelab에서는 Hilt를 사용하여 종속 항목 삽입을 실행하는 Android 앱을 빌드해 보겠습니다.

developer.android.com

 

 

사실 ApplicationComponent.class가 애초부터 import 가 안되었음ㅎ

해당 클래스는 대거에서 특정시점에 Deprecate -> Delete 되었다고 한다.

SingletonComponent로 대체되었다고..

실제 상황이면 대체 클래스를 이용하겠지만.. 이건 코드랩이니까 최대한 코드랩과 싱크를 맞추기 위해 다운그레이드하는걸로..

 

Hilt version 을 바꾸어주니 임포트 완... 해결

 

근데 구글은 라이브러리 업뎃 푸시하고 빌드를 안해본건가....??????

 

build.gradle(project)

 

변경전 

ext.hilt_version = '2.40.1'

변경후

ext.hilt_version = '2.28.3-alpha'

 

이렇게 버전을 바꿔주면 코드랩을 끝까지 따라갈 수 있다.....

 

출처

 

728x90

+ Recent posts