안드로이드 Kotlin Hilt로 의존성 주입(DI) 사용하기 2편
개발환경
- 안드로이드 스튜디오 4.1.1
- JDK 1.8
- Kotlin 1.4.20
- 모든 코드는 https://github.com/aispark/myhilt에 있습니다.
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편

댓글
댓글 쓰기