안드로이드 Kotlin Hilt로 의존성 주입(DI) 사용하기 2편

개발환경

Hilt 모듈

생성자 삽입할 수 없는 상황(외부 라이브러리, 인터페이스일 경우)에서는 Hilt 모듈을 사용하여 Hilt에 바인딩 정보를 제공할 수 있습니다. 


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

@Provides
fun provideHashcode() = hashCode().toString()
}

필드 삽입을 실행할 수 있는 각 Android 클래스마다 @InstallIn 주석에 참조할 수 있는 관련 Hilt 구성요소가 있습니다. 각 Hilt 구성요소는 해당 Android 클래스에 결합을 삽입해야 합니다. ApplicationComponent는 인젝터 되는 클래스가 Applicaiton 입니다.


@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var singletonClass: SingletonClass

@Inject
lateinit var hashcode: String

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

Log.d("singleton", singletonClass.hashCode().toString())
Log.d("singleton", "hashcode: $hashcode")
}
}

다른 Activity나 Fragment에서도 String 타입을 인젝트 받으면 동일한 hashcode값을 볼 수 있습니다.


동일한 타입에 대한 바인딩

@Provides로 모듈을 정의할때 동일한 유형이 있을 경우에는 @Qualifier로 동일한 유형을 식별 할 수 있습니다.


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

@Provides
fun provideTestHashcode() = hashCode().toString()

}

String 타입으로 정의한 후 빌드하면 error: [Dagger/DuplicateBindings] java.lang.String is bound multiple times String 타입이 여러번 바인딩 되었다는 에러가 발생합니다.



@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class Hashcode()


@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class TestHashcode()

애노테이션을 생성합니다.



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

@Hashcode
@Provides
fun provideHashcode() = hashCode().toString()

}

모듈에 생성한 애노테이션을 지정해 줍니다.



@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var singletonClass: SingletonClass

@Hashcode
@Inject
lateinit var hashcode: String

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

Log.d("singleton", singletonClass.hashCode().toString())
Log.d("singleton", "hashcode: $hashcode")
}
}

의존성을 받을 클래스에서도 애노테이션을 지정하면 빌드에 성공 할 수 있습니다.


ViewModel에 의존성 주입


dependencies {

...
def lifecycle_version = "2.2.0"

// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
}

app/build.gradle 파일에 추가합니다.



class MainViewModel @ViewModelInject constructor(
private val singletonClass: SingletonClass): ViewModel() {
fun getHashcode(): String {
return singletonClass.hashCode().toString()
}
}

@ViewModelInject로 지정하면 생성자의 매개변수 중 타입이 일치하면 의존성이 주입 됩니다.



@AndroidEntryPoint
class MainFragment : Fragment(R.layout.fragment_main) {
@Inject
lateinit var singletonClass: SingletonClass

@Hashcode
@Inject
lateinit var hashcode: String

private val viewModel:MainViewModel by viewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
button.setOnClickListener {
val intent = Intent(requireContext(), SecondActivity::class.java)
startActivity(intent)
}

Log.d("singleton", singletonClass.hashCode().toString())
Log.d("singleton", "hashcode: $hashcode")
Log.d("singleton", "viewmodel: ${viewModel.getHashcode()}")
button2.setOnClickListener {
findNavController().navigate(R.id.action_mainFragment_to_secondFragment)
}
}
}

singletonClass.hashCode().toString()과 viewModel.getHashcode()가 동일한 hashcode를 출력하는걸 확인 할 수 있습니다.





안드로이드 Kotlin Hilt로 의존성 주입(DI) 사용하기 1편


댓글