- UnderBar 긋기

 val underlinedText = SpannableString(viewText).apply {
        setSpan(UnderlineSpan(), 0, viewText.length, 0)
    }
    
    binding.tv.text = underlinedText

Hilt란?

Android용 DI(Dpependency Injection: 의존성 주입) 프레임 워크로, Google이 안드로이드 개발을 위해 Dagger를 기반으로 제공하는 Library이다. Dagger의 복잡한 설정을 단순화 하여 의존성 주입을 쉽게 사용 할 수 있도록 도와준다.

Hilt를 사용하는 이유

  1. 의존성 관리의 효율화
  2. → Hilt는 객체의 생성과 라이프사이클을 자동으로 처리하기 때문에 개발자가 수동으로 의존성을 생성하고 관리할 필요가 없음. Activity, Fragment, ViewModel등의 컴포넌트와 자연스럽게 통합됨
  3. 코드 재사용성 증가
  4. →Hilt는 Module을 통해 의존성을 정의하여 여러 클래스에서 같은 의존성을 쉽게 재사용할 수 있음
  5. 테스트 편의성 향상
  6. → 의존성을 주입하기 때문에 실제 객체 대신 목객체를 쉽게 주입하여 테스트를 단순화할 수 있음

Hilt의 종류

  • @HiltAndroidApp (Application)
  • Hilt를 사용하는 모든앱은 Application Class에 해당 어노테이션을 적용해야 함 (Hilt의 코드 생성을 트리거 시킴)
  • @AndroidEntryPoint (Activity, Fragment)@AndroidEntryPoint가 지정된 Service를 사용하는 Activity에도 @AndroidEntryPoint를 지정해야 함
  • Android Component(Activity, Fragment, View, Service, BroadcastReceiver)에 사용할 수 있는 어노테이션으로 @Inject가 달린 필드에 의존성 주입을 한다.
  • @EntryPoint
  • @AndroidEntryPoint를 사용하는곳이 아닌 다른곳에서 의존성주입이 필요한 경우에 사용한다.
  • @Module (Interface나 외부 Library)
  • Interface, Builder Pattern을 사용한 경우(외부 라이브러리 클래스 및)에 사용하며 객체 생성 방법을 정의하여 @Inject가 가능하도록 만들어 준다.
  • @InstallIn (해당 모듈을 지정한 컴포넌트에 설치)
    @Module
    @InstallIn(ActivityComponent::class)
    abstract class CalculatorModule {
    
        @Binds
        abstract fun bindCalculator(impl: CalculatorImpl): Calculator
    
    }
    
    @InstallIn에 들어가는 컴포넌트 종류
    1. SingletonComponent::class → 앱 전체 싱글톤으로 유지되는 객체를 주입 (앱이 켜져있는 동안 유지) → 주로 앱 전체에 유지되는 객체를
    2. ActivityRetainedComponet::class → 액티비티가 살아있는 동안 유지(화면회전시에도 유지)
    3. ActivityComponent::class → 액티비티 생명주기에 맞춰서 생성/파괴
    4. FragmentComponet::class → 프래그먼트 생명주기에 맞춰서 생성/파괴
    5. ViewComponent::class → 안드로이드 View 생명주기에 맞춰서 생성/파괴
    6. ViewModelComponent::class → ViewModel의 생명주기에 맞춰서 생성/파괴
    7. ServiceComponent::class → 서비스 생명주기에 맞춰서 생성/파괴
  • @Module이나 @EntryPoint 어노테이션과 함께 사용해야 하며 @InstallIn을 이용해서 모듈을 어느 컴포넌트에 설치할지 정할 수 있다.
  • @Binds (Interface의 구현체)
  • 인터페이스와 구현체간에 연결을 해준다. (추상 클래스, 추상 함수만 가능)
  • @Provides
  • 복잡한 객체 생성시 사용하며 함수 안에서 직접 구현체를 생성 한다. 일반 클래스나 객체에서 사용 가능
  • @ Inject클래스 간 의존성을 명확히 분리할 수 있어 코드의 결합도를 낮출 수 있음
  • 생성자, 필드, 메서드에 사용 가능

Hilt 적용

Interface, Retrofit, ViewModel에서 주로 사용 됨

  • libs.versions.toml
  • [versions]
     hilt = "2.49" hiltPlugin = "2.49"
  • [libraries]
  • hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt"}
  • hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt"} 
  • [plugins]
  • hilt = { id = "com.google.dagger.hilt.android", version.ref = "hiltPlugin" }
  •  
  • build.gradle.kts(:app)
  • plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) alias(libs.plugins.hilt) id("kotlin-kapt") } android { hilt { enableAggregatingTask = false } } dependencies { //hilt implementation(libs.hilt.android) kapt(libs.hilt.compiler) }
  •  
  • 빌드 오류Unable to find method ''java.lang.String com.squareup.javapoet.ClassName.canonicalName()'' 'java.lang.String com.squareup.javapoet.ClassName.canonicalName()'해결 방법build.gradle(:app)모듈에 enableAggregatingTask 코드를 추가한다.
  •  
  • android{ hilt { enableAggregatingTask = false } }
  • 방법1
  • 오류 원인 최신 버전의 hilt에서는 클래스 경로를 집계(aggregate)하는 용도로 JavaPoet를 사용한다. javapoet의 'java.lang.String com.squareup.javapoet.ClassName.canonicalName()'을 찾지 못하는 것이 오류의 원인이다.
  • 오류 현상

@HiltAndroidApp 등록 → @AndroidEntryPoint 등록 → Interfac, Interface Module, InterfaceImpl 생성 →Interface Impl(@Inject 사용), InterfaceModule(@Module, @InstallIn, @Bind or @Provides@Singleton)

Activity, Fragment → @AndroidEntryPoint

ViewModel → @HiltViewModel

binding.view.layoutParams.height → layoutParams를 입력하지 않고 binding.view.height만을 입력하는 경우 0이 출력됨

textView의 경우에는 binding.textView.lineHeight를 사용해야 해당 TextView의 높이를 구할 수 있다.

//화면상에 보여지는 절대값 Screen Height값
fun getScreenHeight(context: Context): Int {
    val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    //R: API Level30 (Android11)
    return if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.R) {
        val windowMetrics = wm.currentWindowMetrics
        val insets = windowMetrics.windowInsets
            .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
        windowMetrics.bounds.height() - insets.bottom - insets.top
    } else { //Android11 이하
        val displayMetrics = DisplayMetrics()
        wm.defaultDisplay.getMetrics(displayMetrics)
        displayMetrics.heightPixels
    }
}

'Android개발 > Kotlin' 카테고리의 다른 글

[Android][Kotlin]View의 Height구하기  (0) 2025.04.30
[Android][Kotlin]SpannableString  (0) 2025.04.30
[Android][Kotlin]Hilt  (0) 2025.04.30
[Android][Kotlin]null관련 코드(!!, ?:, ?, let)  (0) 2025.04.15
[Android][Kotlin]Bitmap정리  (0) 2025.04.15

!!   

해당 변수의 타입이 Null이 아님을 강제로 지정해준다.

(예상치 못한 Null이 발생시 ANR을 발생시키기 때문에 가급적이면 지양하는 것이 바람직하다.)

 

?:

엘비스 연산자로 해당 변수가 Null일경우 Null대신 임의의 값을 지정해서 넣어준다.

 

해당 변수가 null인경우 ?뒤의 코드는 실행하지 않고 결과값을 null로 지정한다.

 

a?.let{}

a가 Null이 아닌 경우에만 let안의 블록 구문을 실행한다.

 

'Android개발 > Kotlin' 카테고리의 다른 글

[Android][Kotlin]View의 Height구하기  (0) 2025.04.30
[Android][Kotlin]SpannableString  (0) 2025.04.30
[Android][Kotlin]Hilt  (0) 2025.04.30
[Android][Kotlin]View의 Height구하기  (0) 2025.04.15
[Android][Kotlin]Bitmap정리  (0) 2025.04.15

+ Recent posts