Skip to content

Hilt throws an exception when starting instrumented test if application is already installed #5143

Open

Description

@MilanVidic

If application is already installed on the emulator, when triggering any instrumented test through Android Studio play button ▶, Hilt throws an exception:
java.lang.RuntimeException: Unable to start activity ComponentInfo{###/###.MainActivity}: java.lang.IllegalStateException: The component was not created. Check that you have added the HiltAndroidRule.

  • If application is not already installed on the emulator, when triggering any instrumented test, test runs normally.
  • If any instrumented test is run via terminal and gradle command ./gradlew :module:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=classUnderTest#test, test runs normally independent if app is installed or not.
  • If any instrumented test is run on emulator with Android 13 it runs normally, fails on Android 15. Android 14 not tested. Some other repo which uses same Hilt setup runs normally on Android 15. Emulator runs custom AOSP 13/15.

Usually this exception means something is not correctly set up in the test, but I believe everything is fine there since it runs normally on Android 13, through gradle command and if app is not installed. Issue is somewhere in our setup/Android version/Android studio gradle config.

We use kapt, but when I migrated to ksp, same behavior occurred.

Tested on different versions of Android Studio(latest included, Panda 2 | 2025.3.2), same behavior.

hilt: 2.58
kotlin: 2.2.20
jvmTarget: 17
agp:8.13.0

Unfortunately I do not have minimal reproducible code.

Activity

  1. bcorso commented on Mar 17, 2026

    @bcorso

    Hi @MilanVidic, can you show the full stack trace that comes with the IllegalStateException?

    Typically, you will hit this when something tries to access the component before your HiltAndroidRule has a chance to create the component for the particular test case. For example, this can happen if you have a Service that tries to inject too early. For these cases you typically have to use @EarlyEntryPoint. The stacktrace should give more information about when/where this is being called.

  2. MilanVidic commented on Mar 20, 2026

    @MilanVidic
    Author

    Hi @bcorso, here is the stack trace:

    > Task :module:connectedDebugAndroidTest
    Test run failed to complete. Instrumentation run failed due to Process crashed.
    Logcat of last crash: 
    Process: ###.###.###.###, PID: 23815
    java.lang.RuntimeException: Unable to start activity ComponentInfo{###.###.###.###/###.###.###.###.MainActivity}: java.lang.IllegalStateException: The component was not created. Check that you have added the HiltAndroidRule.
    	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4129)
    	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4316)
    	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:222)
    	at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133)
    	at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103)
    	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80)
    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2719)
    	at android.os.Handler.dispatchMessage(Handler.java:109)
    	at android.os.Looper.loopOnce(Looper.java:232)
    	at android.os.Looper.loop(Looper.java:317)
    	at android.app.ActivityThread.main(ActivityThread.java:8787)
    	at java.lang.reflect.Method.invoke(Native Method)
    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:591)
    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:871)
    Caused by: java.lang.IllegalStateException: The component was not created. Check that you have added the HiltAndroidRule.
    	at dagger.hilt.internal.Preconditions.checkState(Preconditions.java:83)
    	at dagger.hilt.android.internal.testing.TestApplicationComponentManager.generatedComponent(TestApplicationComponentManager.java:96)
    	at ###.###.###.###.CustomHiltApplication_Application.generatedComponent(CustomHiltApplication_Application.java:30)
    	at dagger.hilt.EntryPoints.get(EntryPoints.java:59)
    	at dagger.hilt.android.EntryPointAccessors.fromApplication(EntryPointAccessors.kt:35)
    	at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager$1.create(ActivityRetainedComponentManager.java:111)
    	at androidx.lifecycle.ViewModelProvider$Factory.create(ViewModelProvider.android.kt:149)
    	at androidx.lifecycle.viewmodel.internal.ViewModelProviderImpl_androidKt.createViewModel(ViewModelProviderImpl.android.kt:35)
    	at androidx.lifecycle.viewmodel.internal.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel(ViewModelProviderImpl.kt:59)
    	at androidx.lifecycle.viewmodel.internal.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel$default(ViewModelProviderImpl.kt:43)
    	at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.android.kt:90)
    	at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.android.kt:104)
    	at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager.createComponent(ActivityRetainedComponentManager.java:143)
    	at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager.generatedComponent(ActivityRetainedComponentManager.java:128)
    	at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager.generatedComponent(ActivityRetainedComponentManager.java:42)
    	at dagger.hilt.EntryPoints.get(EntryPoints.java:59)
    	at dagger.hilt.android.internal.managers.ActivityComponentManager.createComponent(ActivityComponentManager.java:105)
    	at dagger.hilt.android.internal.managers.ActivityComponentManager.generatedComponent(ActivityComponentManager.java:71)
    	at ###.###.###.###.Hilt_MainActivity.generatedComponent(Hilt_MainActivity.java:69)
    	at ###.###.###.###.Hilt_MainActivity.inject(Hilt_MainActivity.java:91)
    	at ###.###.###.###.Hilt_MainActivity$1.onContextAvailable(Hilt_MainActivity.java:45)
    	at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.kt:84)
    	at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:358)
    	at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:216)
    	at ###.###.###.###.Hilt_MainActivity.onCreate(Hilt_MainActivity.java:57)
    	at ###.###.###.###.MainActivity.onCreate(MainActivity.kt:52)
    	at android.app.Activity.performCreate(Activity.java:9019)
    	at android.app.Activity.performCreate(Activity.java:8997)
    	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1528)
    	at androidx.test.runner.MonitoringInstrumentation.callActivityOnCreate(MonitoringInstrumentation.java:766)
    	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4111)
    	... 13 more
    
    

    We do have a Service which is launched when app is started, but that Service is defined in a separate gradle module.

  3. bcorso commented on Mar 20, 2026

    @bcorso

    Thanks for the full trace!

    Looks like this is happening during Activity#onCreate() so I don't think this is a use case for @EarlyEntryPoints.

    If you can create a minimal repro example that demonstrates this behavior I can take a look, otherwise you will have to do some further debugging. I would start by looking at TestApplicationComponentManager which controls the component state. You can look at both Android 13 and 15 and see what's different between the two cases and maybe we can narrow this down a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions