#android #kotlin #dagger-hilt
#Android #kotlin #кинжал-рукоять
Вопрос:
Я пытался решить свою проблему, но ничего не могу найти…
MyApp.kt :
@HiltAndroidApp
class MyApp: Application()
MainActivity.kt
@AndroidEntryPoint
class MainActivity: AppCompatActivity()
MyFragment.kt
class MyFragment: Fragment() {
private val myViewModel: MyViewModel by viewModels()
}
MyViewModel.kt
class MyViewModel @ViewModelInject constructor(
application: Application,
myRepository: MyRepository, {*}
@Assisted private val state: SavedStateHandle,
): AndroidViewModel(application)
MyRepository.kt
interface MyRepository {
fun test()
}
class MyRepositoryImpl @Inject constructor(): MyRepository {
override fun test() { print("") }
}
MyModule.kt
@Module
@InstallIn(SingletonComponent::class)
abstract class MyModule {
@Binds
abstract fun bindsMyRepository(impl: MyRepositoryImpl): MyRepository
}
Если я прокомментирую строку с помощью «{*}», она будет работать нормально, но поскольку я пытаюсь добавить свой пользовательский репозиторий, я получил эту ошибку :
java.lang.RuntimeException: не удается создать экземпляр класса MyViewModel
Вызвано: java.lang.Исключение NoSuchMethodException: [класс android.app.Application]
У вас есть какие-либо идеи о том, чего мне не хватает?
Спасибо вам!
Дополнительная информация: Я забыл упомянуть, что это многомодульное приложение.
В первом модуле есть базовое приложение: MainActivity, манифест (1)
Во втором модуле находится основное приложение: MyApp, манифест (2)
В третьем модуле есть модуль : MyFragment, MyViewModel, MyRepository и MyModule, манифест (3)
Манифесты выглядят так:
(1)
<manifest...>
<application...
android:name=".secondModule.MyApp">
</manifest>
(2)
<manifest...>
<application>
<provider...></provider>
</application>
</manifest>
(3)
<manifest.../>
Комментарии:
1. для чего вам нужен интерфейс?
2. Я максимально упростил свой код 🙂 У меня есть репозиторий, который вызывает класс Api, но пока я должен удалить его, пока он не заработает
3. Вам нужно будет добавить некоторые зависимости build.gradle, потому что это звучит как несоответствие версий Dagger Hilt.
4. Моя текущая версия (после ответа IR42): кинжал: 2.31.1, Рукоять: 2.31-альфа
Ответ №1:
- Сначала аннотируйте свой фрагмент
@AndroidEntryPoint
class MyFragment: Fragment() {
private val myViewModel: MyViewModel by viewModels()
}
- Во-вторых, вы должны расширить ViewModel вместо AndroidViewModel
class MyViewModel @ViewModelInject constructor(
@Application context : Context ,
myRepository: MyRepository, {*}
@Assisted private val state: SavedStateHandle,
): ViewModel()
- Замените SingletonComponent на ApplicationComponent
@Module
@InstallIn(ApplicationComponent::class)
abstract class MyModule {
@Binds
abstract fun bindsMyRepository(impl: MyRepositoryImpl): MyRepository
}
PS: Не забудьте добавить свой класс приложения ( MyApp) в файл манифеста
Комментарии:
1. Спасибо за ваш быстрый ответ, я изменил свои два файла. Но у меня все еще есть эта ошибка: java.lang. Исключение IllegalStateException: фрагменты Hilt должны быть прикреплены к основной активности @AndroidEntryPoint (у меня есть аннотация «@AndroidEntryPoint» как для activity, так и для fragment) Чего я не могу сделать, так это использовать аннотацию «@Application», является ли «@ApplicationContext» тем же самым?
2. Я снова отредактировал ответ, проверьте его и посмотрите, работает ли он
3. Возможно, проблема здесь. Это многомодульное приложение. В модуле приложения my androidпроявляется в качестве атрибутов «android:name=»MyApp»». В другом модуле (где принадлежит фрагмент) манифест почти пуст, это просто объявление
4. можете ли вы добавить некоторый код вашего файла манифеста в свой код!
5. Для вашей замены эта аннотация неизвестна в hilt версии 2.31-aplha
Ответ №2:
Вы должны использовать @AndroidEntryPoint
для своих фрагментов
@AndroidEntryPoint
class MyFragment: Fragment() {
private val myViewModel: MyViewModel by viewModels()
}
Также ApplicationComponent
был удален в Dagger 2.30
, но он используется в androidx.hilt:hilt
( @ViewModelInject
) .
Они добавлены ApplicationComponent
обратно из 2.31.1
-за библиотеки, упомянутой выше.
Обновите версию Dagger до 2.31.1
(используйте SingletonComponent
вместо ApplicationComponent
) или используйте новые функциональные модели просмотра Hilt
@HiltViewModel
class MyViewModel @Inject constructor(
private val application: Application,
myRepository: MyRepository,
private val state: SavedStateHandle,
): ViewModel()
Комментарии:
1. Спасибо за ваш ответ, я обновил dagger до 2.31.1. Я могу использовать аннотацию HiltViewModel, и я попробовал ваше решение, и у меня все та же проблема: «IllegalStateException: фрагменты Hilt должны быть прикреплены к действию AndroidEntryPoint»., Даже если я аннотирую все свои фрагменты и свою основную активность с помощью «AndroidEntryPoint».
2. @JohnDoe У вас есть какие-либо другие действия без
@AndroidEntryPoint
использования фрагментов@AndroidEntryPoint
?3. Нет, я не вижу никаких действий, которые содержат фрагмент с AndroidEntryPoint без AndroidEntryPoint тоже