Dagger를 통해 DI 구현 중 ViewModelProvider.Factory를 의존성 주입하여 구현하는 방법을 정리해본다.
코드들은 Kotlin으로 작성했다.
import androidx.lifecycle.ViewModel
import dagger.MapKey
import java.lang.annotation.*
import java.lang.annotation.Retention
import java.lang.annotation.Target
import kotlin.reflect.KClass
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
class ViewModelFactory @Inject constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
var creator: Provider<ViewModel>? = creators[modelClass]
if (creator == null) {
for ((key, value) in creators) {
if (modelClass.isAssignableFrom(key)) {
creator = value
break
}
}
}
if (creator == null) throw IllegalArgumentException("unknown model class $modelClass")
try {
return creator.get() as T
} catch (e: Exception) {
throw IllegalArgumentException(e)
}
}
}
@Module
@InstallIn(ApplicationComponent::class)
abstract class ViewModelModule {
@Binds
@Singleton
abstract fun bindsViewModelProviderFactory(viewModelFactory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@IntoMap
@ViewModelKey(LoginViewModel::class)
abstract fun bindsLoginViewModel(loginViewModel: LoginViewModel): ViewModel
}
@AndroidEntryPoint
class LoginActivity : AppCompatActivity() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var loginViewModel: LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
loginViewModel = ViewModelProvider(this, viewModelFactory).get(LoginViewModel::class.java)
...
}
}
참고 블로그들
https://dev-vero.tistory.com/4
Dagger2 적용하기 (2) - Injection Activity/ViewModel
1. ViewModelKey annotation 생성 @MustBeDocumented @MapKey @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) internal annotation class ViewModelKey(val value: KClass ) 2. Vie..
dev-vero.tistory.com
https://jaejong.tistory.com/148
[Kotlin] @JvmSuppressWildCards 의미
@JvmSuppressWildcards 애노테이션 @JvmSuppressWildcards 코틀린 컴파일러는 제네릭을 기본적으로 List 을 List<? extends String> 형태로 변환합니다 이런형태의 자동변환을 방지하는 방법은 @JvmSuppressWildc..
jaejong.tistory.com
'Android' 카테고리의 다른 글
| [Android] Hilt: Dependency Injection Made Easy (0) | 2023.02.26 |
|---|---|
| [Android] ProgressBar setIndeterminateDrawable 오류 (0) | 2022.05.12 |
| [Android] Gson 과 android.location.Location (0) | 2022.04.15 |
| [Android] Material Indeterminate Progress Drawable 커스텀 (0) | 2022.02.24 |
| [Android] 지난 주 날짜 가지고 오기 (0) | 2021.08.03 |