-1

I have no idea what wents wrong. I tried most approaches on stackoverflow but nothing works. All i figured out that it has something to do with my LdapContactsScreen

java.lang.IllegalStateException: Given component holder class com.kontron.contacts.MainActivity does not implement interface dagger.hilt.internal.GeneratedComponent or interface dagger.hilt.internal.GeneratedComponentManager
                                                                                                        at dagger.hilt.EntryPoints.get(EntryPoints.java:62)
                                                                                                        at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.createInternal(HiltViewModelFactory.java:206)
                                                                                                        at androidx.hilt.navigation.HiltViewModelFactory.create(HiltNavBackStackEntry.kt:75)
                                                                                                        at androidx.hilt.navigation.compose.HiltViewModelKt.createHiltViewModelFactory(HiltViewModel.kt:95)
                                                                                                        at com.kontron.contacts.ui.presentation.ldap_contacts_screen.LdapContactsScreenKt.LdapContactsScreen(LdapContactsScreen.kt:130)
                                                                                                        at com.kontron.contacts.MainActivity$onCreate$1$1$1$2$1$2.invoke(MainActivity.kt:114)
                                                                                                        at com.kontron.contacts.MainActivity$onCreate$1$1$1$2$1$2.invoke(MainActivity.kt:113)
                                                                                                        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:139)
                                                                                                        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
                                                                                                        at androidx.navigation.compose.NavHostKt$NavHost$14$1.invoke(NavHost.kt:308)
                                                                                                        at androidx.navigation.compose.NavHostKt$NavHost$14$1.invoke(NavHost.kt:306)
                                                                                                        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)

This is my configuration:

settings.gradle.kts

pluginManagement {
    repositories {
        google {
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "Contacts"
include(":app")

libs.versions.toml

[versions]
agp = "8.5.0"
compose = "1.0.0-beta01"
hiltAndroid = "2.49"
#hiltAndroidCompiler = "2.28-alpha"
#hiltLifecycleViewmodel = "1.0.0-alpha03"
daggerCompiler = "2.51.1"
hiltNavigationCompose = "1.2.0"
kotlin = "1.9.0"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.3"
activityCompose = "1.9.0"
composeBom = "2024.06.00"
material = "1.6.8"
navigationCompose = "2.7.7"
unboundidLdapsdk = "6.0.7"
media3Common = "1.3.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-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" }
androidx-material = { module = "androidx.compose.material:material", version.ref = "material" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
compose = { module = "com.github.bumptech.glide:compose", version.ref = "compose" }
dagger = { module = "com.google.dagger:dagger", version.ref = "hiltAndroid" }
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "daggerCompiler" }
#androidx-hilt-lifecycle-viewmodel = { module = "androidx.hilt:hilt-lifecycle-viewmodel", version.ref = "hiltLifecycleViewmodel" }
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
unboundid-ldapsdk = { module = "com.unboundid:unboundid-ldapsdk", version.ref = "unboundidLdapsdk" }
androidx-media3-common = { group = "androidx.media3", name = "media3-common", version.ref = "media3Common" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

The Project gradle: build.gradle.kts

plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.jetbrains.kotlin.android) apply false
}

Thats my app gradle:

plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.jetbrains.kotlin.android)
    id("com.google.devtools.ksp") version "1.9.0-1.0.13"
//    id("com.google.dagger.hilt.android")
}

android {
    namespace = "com.kontron.contacts"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.kontron.contacts"
        minSdk = 28
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary = true
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.1"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
}

dependencies {
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    implementation(libs.androidx.material)
    implementation(libs.compose)
    implementation(libs.hilt.android)
    implementation(libs.androidx.navigation.compose)
    implementation(libs.androidx.hilt.navigation.compose)
//    implementation(libs.androidx.hilt.lifecycle.viewmodel)
    implementation (libs.dagger)
    annotationProcessor(libs.androidx.hilt.compiler)


    implementation(libs.androidx.lifecycle.viewmodel.compose)
    implementation(libs.unboundid.ldapsdk)
    implementation(libs.androidx.media3.common)

    implementation(fileTree("dir" to "libs", "include" to listOf("*.aar")))

    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
}

My MainActivity looks like this:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        checkPermissions()

        setContent {
            val navController = rememberNavController()
            ContactsTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background,
                ) {
                    Scaffold(
                        bottomBar = { BottomNavigationBar(navController) }
                    ) { padding ->
                        NavHost(
                            navController = navController,
                            startDestination = BottomNavItem.LdapContacts.screenRoute
                        ) {
                            val pad = padding
                            composable(BottomNavItem.McxContacts.screenRoute) {
                                McxContactsScreen(navController)
                            }

                            composable(BottomNavItem.LdapContacts.screenRoute) {
                                LdapContactsScreen(navController)
                            }

                            composable(
                                route = Routes.ContactDetailView.route +
                                        "/{contactId}" +
                                        "/{contactType}"
                            ) { navBackStackEntry ->
                                val viewModel: ContactDetailViewModel by viewModels()
                                val arguments = requireNotNull(navBackStackEntry.arguments)
                                viewModel.contactId = arguments.getString("contactId")
                                viewModel.contactType = arguments.getString("contactType")
                                Log.d(TAG, "contactId: ${arguments.getString("contactId")}")
                                Log.d(TAG, "contactType: ${arguments.getString("contactType")}")

                                ContactDetailView(viewModel, navController)
                            }

                            composable(
                                route = Routes.LdapContactsDetailsView.route + "/{mcxid}"
                            ) { nbe ->
                                val arguments = requireNotNull(nbe.arguments)
                                val id = arguments.getString("mcxid")
                                    ?: throw Exception("No MCXID found")
                                LdapContactsDetailsScreen(mcxid = id)
                            }
                        }
                    }
                }
            }
        }
    }

I need an idea what this error refers to. Most of the Stack Overflow Answers are too old to get a picture.

Update: It seems that the viewModel is causing the error. When I comment out the my Compose view where the viewModel sits, the app starts correctly. If i call the viewModel in the composable()- it fails again.

composable(BottomNavItem.LdapContacts.screenRoute) {
  val viewModel: LdapContactsScreenViewModel = hiltViewModel()
  //LdapContactsScreen(navController)
}

Thats what the viewModel looks like:

private const val TAG = "LdapContactsScreenViewModel"

@HiltViewModel
class LdapContactsScreenViewModel
@Inject
constructor(
    private val sharedPreferences: ISharedPreferences,
    private val ldapConnection: ILdapRepository,
    private val app: BaseApplication
) : ViewModel() {
    private val timestamp = sharedPreferences.getSyncTimestamp() ?: setTimestamp()
    val state: MutableState<LdapContactScreenState> = mutableStateOf(LdapContactScreenState.READY)
    val contacts: MutableState<List<McxLdapContact>> = mutableStateOf(listOf())

    var errorMessage: String = ""

    init {
        getLdapContacts()
        if (timestamp.isEmpty()) {
            setTimestamp()
        }
    }
}

Im adding the manifest as wished:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-feature
        android:name="android.hardware.telephony"
        android:required="false" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.#READ_PROFILE" />
    <uses-permission android:name="android.permission.#WRITE_PROFILE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_MEDIA_STORAGE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application
        android:name=".BaseApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Contacts"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.Contacts">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
2
  • Can you share a Github repo with sample code to reproduce the issue? Commented Jul 8 at 14:07
  • Are you sure you annotated your MainActivity with @AndroidEntryPoint? If that doesn't solve your problem then please also provide your AndroidManifest.xml and your Application class. We also need to see all classes that you want to inject with Hilt and how they are called.
    – Leviathan
    Commented Jul 8 at 17:54

0