Hilt Scopes & Components Quiz

ARCHITECTURE › Dependency Injection

A binding has no scope annotation. What happens each time it is requested?

Answer: Hilt creates a new instance every time

By default all Hilt bindings are unscoped, so Hilt creates a fresh instance on every request rather than caching one.

Which component's lifetime survives a configuration change such as a screen rotation?

Answer: ActivityRetainedComponent, which lives through config changes

ActivityRetainedComponent is created at the first Activity#onCreate and destroyed at the last onDestroy, persisting across configuration changes; ActivityComponent and its children are recreated.

A dependency is annotated @ViewModelScoped. Two distinct ViewModel instances request it. What do they get?

Answer: Each ViewModel gets its own single instance

@ViewModelScoped shares one instance across all dependencies within a single ViewModel, but each separate ViewModel instance receives its own distinct instance.

You want exactly one instance of a repository shared across multiple ViewModels on the same screen flow but not the whole app. Best scope?

Answer: Use @ActivityRetainedScoped to share one repo across ViewModels.

@ActivityRetainedScoped shares one instance across ViewModels (which live under ActivityRetainedComponent) and survives config changes, without making it an app-wide singleton.

Which is the most likely consequence of scoping a class that holds an Activity Context to @Singleton?

Answer: The Activity is leaked because the Singleton outlives it

A Singleton lives for the entire process, so holding an Activity Context keeps the destroyed Activity in memory, causing a leak; an application Context or narrower scope avoids it.

Which Hilt component provides @HiltViewModel ViewModels and shares the ViewModel's lifecycle?

Answer: ViewModelComponent, scoped to the ViewModel lifecycle

Hilt ViewModels are provided by the ViewModelComponent, which follows the same lifecycle as the ViewModel and can survive configuration changes.

A binding is installed only in ActivityComponent. From where can it be injected?

Answer: From ActivityComponent and its Fragment/View children

A binding is visible to its own component and any child below it in the hierarchy, so an ActivityComponent binding reaches Fragment and View components but not parents or siblings.

Which annotation and component pair correctly caches a single instance for the lifetime of a bound Service?

Answer: @ServiceScoped on a module installed in ServiceComponent

ServiceComponent holds @ServiceScoped bindings, created at the Service's onCreate and destroyed at its onDestroy, so the cached instance matches the Service lifetime.

You need a Context that lives for the whole app and is safe to hold in a @Singleton. Which Hilt-predefined qualifier do you inject?

Answer: @ApplicationContext Context for the app's lifetime

Hilt predefines @ApplicationContext (the application Context) and @ActivityContext; the application Context outlives any Activity, so storing it in a Singleton causes no leak.

A Hilt @Module is written with @Provides methods but no @InstallIn annotation. What is the outcome?

Answer: Compilation fails because @InstallIn must be declared

Hilt requires every module to declare its component with @InstallIn; omitting it is a build error (only suppressible with @DisableInstallInCheck for special test cases).

A module installed in SingletonComponent declares a binding annotated @ActivityScoped. What happens?

Answer: A compile-time error: scope doesn't match the component

A scope annotation must be one the install component actually supports; @ActivityScoped is not valid in SingletonComponent, so Hilt fails the build.

A @AndroidEntryPoint BroadcastReceiver needs an injected dependency. Receivers have no generated Hilt component, so from where are their members injected?

Answer: SingletonComponent

Hilt does not generate a component for BroadcastReceiver; it performs members injection directly from the SingletonComponent.

A custom View annotated @AndroidEntryPoint must access bindings scoped to its host Fragment. What is required?

Answer: Add @WithFragmentBindings so it uses ViewWithFragmentComponent

@WithFragmentBindings makes the entry-point View use ViewWithFragmentComponent, which can see Fragment-scoped bindings; a plain ViewComponent only reaches Activity-level bindings.

You must obtain a Hilt binding inside a ContentProvider, which Hilt cannot annotate as a normal @AndroidEntryPoint. What is the idiomatic approach?

Answer: Use an @EntryPoint interface via EntryPointAccessors

For classes outside Hilt's standard entry points, you define an @EntryPoint-annotated interface installed in the right component and fetch bindings through EntryPointAccessors.

Back to Hilt Scopes & Components