Skip to content
tezvyn:

How do you inject two different OkHttpClient instances with Hilt?

Source: developer.android.comMediumHow cards are made

How do you inject two different OkHttpClient instances with Hilt?

Tests Hilt qualifiers for same-type bindings. Answer: define a custom @Qualifier (or @Named), annotate two @Provides methods and the injection site. Red flag: manual client creation or subclassing OkHttpClient instead of qualifying the binding.

What's really being asked

Your practical knowledge of Hilt and Dagger qualifiers when multiple dependencies share the same type. The interviewer wants to see that you can disambiguate bindings cleanly without resorting to runtime logic, manual construction, or factory methods that leak creation details into consumers. They are also checking that you understand the difference between a qualifier and scoping, since the two concepts are orthogonal.

The full answer

Four things in order. First, declare a custom qualifier annotation with @Qualifier and @Retention(AnnotationRetention.BINARY) to distinguish the variants. Second, provide two @Provides methods in a @Module, one returning the logging client and one returning the plain client, each annotated with the matching qualifier. Third, at the injection site, annotate the OkHttpClient parameter or property with the same qualifier to tell Hilt which instance to satisfy. Fourth, mention that custom qualifiers are preferred over @Named because they are type-safe, survive refactoring, and avoid string-constant duplication across modules.

The mistakes people make

Several anti-patterns show up here. Some candidates suggest subclassing OkHttpClient or creating wrapper types, which pollutes the domain model to solve a DI framework concern. Others propose using @Binds, which only works when you already have an instance of the concrete type and cannot run builder logic like addInterceptor. Another red flag is manual instantiation inside a ViewModel or Repository, which defeats the purpose of dependency injection and complicates unit testing. Finally, using @Named with string literals is acceptable but inferior because it is brittle and offers no compile-time verification or IDE navigation.

What usually comes next

The interviewer may ask why a custom qualifier beats @Named, or how you would handle the case if both clients are needed in the same class. They might also probe scoping, asking whether these clients should be @Singleton or unscoped, and why sharing a single OkHttpClient pool matters for connection limits and thread safety.

A concrete example

Define annotation class LoggingClient with @Qualifier. In a NetworkModule, write @Provides @LoggingClient fun provideLoggingOkHttpClient(): OkHttpClient = OkHttpClient.Builder().addInterceptor(HttpLoggingInterceptor()).build(). Write a second @Provides method annotated with @NonLoggingClient that returns a plain builder build. In your repository constructor, request the specific one with @LoggingClient okHttpClient: OkHttpClient.

Interview question

You need to inject both a logging and a plain OkHttpClient using Hilt. Which pattern best disambiguates the bindings without leaking creation details into consumers?

  • a.Instantiate the clients manually inside the consuming ViewModels based on a boolean flag
  • b.Subclass OkHttpClient for each variant and bind them with @Binds
  • c.Define a custom @Qualifier, annotate two @Provides methods in a @Module, and annotate the injection sitesCorrect
  • d.Apply @Singleton to one client and @ActivityScoped to the other in the same module
Why?

Custom qualifiers are the type-safe, idiomatic way to distinguish multiple bindings of the same type while keeping construction logic inside the module. Subclassing OkHttpClient and using @Binds is a common anti-pattern because @Binds cannot run builder configuration like addInterceptor, and wrapper types pollute the domain model.

Just read this? Test yourself on what you have been reading.

Read the original → developer.android.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on android — each one lists the topics its interview covers.

See open roles