Intereting Posts
Каковы зарезервированные ключевые слова в Котлине? Kotlin – объявить общий класс с параметром типа, который является общим Импорт не используется в Android Studio Возврат значения, полученного в Kotlin coroutine Факториал с использованием цикла `for` в Котлине В чем разница между arrayListOf и mutableListOf, какая из них лучше? DigestUtils.md5Hex () генерирует неправильное значение хэша при передаче объекта String Как импортировать каталог / полный пакет в Intellij для целей тестирования Преобразование больших чисел в байт в Котлине Параметры аргумента функции kotlin по умолчанию из java Как я могу сказать Kotlin, что массив или коллекция не могут содержать нули? Kotlin с Android DataBinding в Android Studio 3.0 canary 2 Почему я получаю ошибку java.lang.IllegalStateException: экземпляр не инициализирован? Как подключить HazelcastClient к HazelcastServer после перезагрузки сервера Инструменты статического анализа для языка программирования Kotlin?

Переплет в карту с типом KClass

Я пытаюсь привязать подклассы ViewModel к карте своими типами KClass :

 @Module abstract class ViewModelModule { @Binds @IntoMap @ViewModelKey(MyViewModel::class) abstract fun bindsMyViewModel(viewModel: MyViewModel): ViewModel @Binds abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory } 

Но я получаю ошибку компилятора Dagger:

 e: ~/Example/app/build/tmp/kapt3/stubs/debug/com/example/app/injection/AppComponent.java:5: error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method. e: e: public abstract interface AppComponent { e: ^ e: java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at e: com.example.app.ui.ViewModelFactory.<init>(creators) e: com.example.app.ui.ViewModelFactory is injected at e: com.example.app.injection.ViewModelModule.bindViewModelFactory(p0) e: android.arch.lifecycle.ViewModelProvider.Factory is injected at e: com.example.app.ui.MyFragment.setViewModelFactory(p0) e: com.example.app.ui.MyFragment is injected at e: dagger.android.AndroidInjector.inject(arg0) 

Вышеуказанный ViewModelModule включен в мой AppModule , который является модулем моего AppComponent . Таким образом, кинжал должен быть в состоянии предоставить Map<KClass<out ViewModel>, Provider<ViewModel>> требуемую моим ViewModelFactory , но я не могу понять, почему он сбой.


Я также попытался переключить класс аннотации ViewModelKey на Java, взяв вместо параметра KClass параметр Class как конструктора. Затем изменил мой ViewModelFactory чтобы он зависел от Map<Class<out ViewModel>, Provider<ViewModel>> , но произошла ошибка.

При использовании KClass в аннотации он фактически компилируется в Class Java. Но актуальной проблемой является шаблон в java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> который генерирует компилятор Kotlin.

Предполагая, что @ViewModelKey определяется как

 @MapKey annotation class ViewModelKey(val value: KClass<out ViewModel>) 

Вам нужно будет определить сайт инъекции, как

 Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>> 

Использование @JvmSuppressWildcards не позволит компилятору создавать подстановочные знаки.

Я действительно не знаю, почему подстановочные знаки не поддерживаются компилятором Dagger. Вы можете увидеть аналогичную проблему здесь: Кинжал 2: Как ввести карту <Класс <? extends Foo>, Provider <? расширяет Foo >>