В настоящее время я столкнулся с проблемой внедрения внедрения зависимостей в мое приложение, которое я разработал с помощью Jetpack Compose.
Я включил следующие зависимости и плагины для Dagger Hilt:
Файл градиента уровня проекта:
plugins {
...
id("com.google.dagger.hilt.android") version "2.51.1" apply false
}
Файл градиента уровня модуля:
plugins {
...
id("kotlin-kapt")
id("com.google.dagger.hilt.android")
}
dependencies {
...
//hilt
implementation(libs.hilt.android)
kapt(libs.hilt.android.compiler)
implementation(libs.androidx.hilt.navigation.compose)
kapt(libs.androidx.hilt.compiler)
implementation(libs.androidx.hilt.navigation.fragment)
}
kapt {
correctErrorTypes = true
}
В этом каталоге версий:
[versions]
agp = "8.5.0"
hiltAndroid = "2.51.1"
hiltAndroidCompiler = "2.48"
hiltLifecycleViewmodel = "1.0.0-alpha03"
hiltNavigationCompose = "1.2.0"
kotlin = "1.9.0"
coreKtx = "1.13.1"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hiltNavigationCompose" }
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
androidx-hilt-navigation-fragment = { module = "androidx.hilt:hilt-navigation-fragment", version.ref = "hiltNavigationCompose" }
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hiltAndroidCompiler" }
#hilt-android-gradle-plugin seems to be greyed out - it isn't being used
hilt-android-gradle-plugin = { module = "com.google.dagger:hilt-android-gradle-plugin", version.ref = "hiltAndroid" }
[plugins]
#No Hilt-Related plugins, only android-application and kotlin
Я создал HiltViewModel следующим образом:
@HiltViewModel
class GameViewModel @Inject constructor(
private val sample: Sample
) : ViewModel() {
...
}
где Sample — это фиктивный класс, который определяется следующим образом:
class Sample (
context: Context
)
Для справки также включены модуль для внедрения моих зависимостей и мой класс приложения:
import android.app.Application
import com.example.cheesechase.gyroscope.Sample
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun giveSample(context: Application): Sample {
return Sample(context)
}
}
Я добавил аннотацию @AndroidEntryPoint
к своему классу MainActivity, откуда я вызываю составную навигацию (я использую Compose Navigation). Я инициализирую свою модель представления внутри Navigation Composable, используя
val viewModel = hiltViewModel<GameViewModel>()
и передать его на мои экраны как переменную viewModel
. Теперь, когда я пытаюсь запустить код, я получаю следующее исключение:
java.lang.RuntimeException: Cannot create an instance of class com.example.cheesechase.GameViewModel
at androidx.lifecycle.viewmodel.internal.JvmViewModelProviders.createViewModel(JvmViewModelProviders.kt:40)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.android.kt:193)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.android.kt:317)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.android.kt:299)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.android.kt:273)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.kt:128)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:172)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:172)
at androidx.lifecycle.ViewModelProvider$Factory.create(ViewModelProvider.android.kt:158)
at androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release(ViewModelProviderImpl.kt:67)
at androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release$default(ViewModelProviderImpl.kt:47)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.android.kt:91)
at androidx.lifecycle.viewmodel.compose.ViewModelKt__ViewModelKt.get(ViewModel.kt:162)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(Unknown Source:1)
at androidx.lifecycle.viewmodel.compose.ViewModelKt__ViewModel_androidKt.viewModel(ViewModel.android.kt:124)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(Unknown Source:1)
at com.example.cheesechase.navigation.NavigationKt.Navigation(Navigation.kt:84)
at com.example.cheesechase.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:38)
at com.example.cheesechase.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:36)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:118)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:239)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:221)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:989)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:476)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:90)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3302)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3235)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:723)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1071)
at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3599)
at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:631)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:617)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:499)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:471)
Я пробовал перенести инициализацию в MainActivity, а также в другие места, но безрезультатно. Я попробовал изменить и включить плагины и зависимости Gradle. Кроме того, код работает нормально (работает без ошибок), когда я не включаю зависимости в свой конструктор GameViewModel
, например:
@HiltViewModel
class GameViewModel @Inject constructor() : ViewModel() {...}
@Leviathan, я добавил каталог версий. Вся трассировка стека превышает лимит символов для вопроса, поэтому я ограничил ее (надеюсь) важной первой частью. Дайте мне знать, если мне нужно добавить больше
Вероятно, вы пытались добавить весь журнал; Однако трассировка — это единственное, что нам нужно увидеть, это нормально. Но вы добавили только раздел [versions]
из каталога версий, нам же нужно посмотреть и остальные разделы. Но прежде чем вставлять сюда, пожалуйста, удалите все, что не связано с Hilt, то есть используется вашими зависимостями Gradle, которыми вы поделились здесь.
@Leviathan Я добавил каталог версий с соответствующим содержимым.
Проблема в том, что вы смешиваете разные версии Hilt. Если вы обычно используете версию «2.51.1», hilt-android-compiler
(com.google.dagger:hilt-android-compiler
) использует только «2.48».
Я не знаю, почему у вас вообще в каталоге версий две разные версии Hilt, но вам следует удалить эту:
hiltAndroidCompiler = "2.48"
Теперь просто замените его использование на правильную версию hiltAndroid
, и все должно работать.
Пока мы этим занимаемся:
Вам также следует определить плагин hilt в каталоге версий:
[plugins]
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hiltAndroid" }
Теперь вы можете заменить id("com.google.dagger.hilt.android")
в файлах Gradle на alias(libs.plugins.hilt.android)
(обязательно также используйте apply false
в файле Gradle уровня проекта).
Таким образом, у вас будет только одно место, где вы определяете версию Hilt, — в вашем каталоге версий. Если вы хотите обновить версию, просто обновите hiltAndroid
.
Следующие зависимости вам не нужны, удалите их:
kapt(libs.androidx.hilt.compiler)
implementation(libs.androidx.hilt.navigation.fragment)
Затем вы можете удалить выделенные серым цветом записи из каталога версий, чтобы было меньше путаницы.
Вам не нужен модуль Dagger для того, что вы делаете, если вы аннотируете свой класс Sample
следующим образом:
@Singleton
class Sample @Inject constructor(
@ApplicationContext context: Context,
)
Контекст приложения может быть введен Hilt «из коробки».
Не передавайте экземпляры модели представления. После получения с помощью hiltViewModel
вам следует только передавать его свойства и функции другим составным объектам. Если ваши свойства — это потоки или состояния, передавайте только их значения.
Пожалуйста, отредактируйте свой вопрос и добавьте соответствующие части каталога версий. Кроме того, расширьте сообщение об ошибке, прикрепив полную трассировку стека (в виде текста, а не скриншота).