In the documentation on Hilt, it shows this example of injecting a viewmodel into an activity:
@HiltViewModel
class ExampleViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
private val repository: ExampleRepository
) : ViewModel() {
...
}
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
private val exampleViewModel: ExampleViewModel by viewModels()
...
}
But what if ExampleRepository itself has a constructor that requires parameters? How would the code in the activity be different? How do you tell Hilt what parameters to pass to Repository?
CodePudding user response:
there is multiple ways but I'll mention one I use for parameters that are from custom type like retrofit api service or OKHttp you need to provide it like below
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
fun provideOkHttpClient(
@ApplicationContext context: Context,
networkManager: NetworkManager,
authenticator: AuthInterceptor,
preferenceHelper: PreferenceHelper
): OkHttpClient {
val httpLogging = HttpLoggingInterceptor()
httpLogging.level = HttpLoggingInterceptor.Level.BODY
val httpClient = OkHttpClient.Builder()
.addInterceptor(authenticator)
.connectTimeout(5, TimeUnit.MINUTES)
.callTimeout(5, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
if (BuildConfig.BUILD_TYPE == Constants.STAGING_RELEASE)
httpClient.addInterceptor(httpLogging)
httpClient.addInterceptor(ChuckInterceptor(context))
val httpCacheDirectory = File(context.cacheDir, "responses")
val cacheSize: Long = 10 * 1024 * 1024
val cache = Cache(httpCacheDirectory, cacheSize)
httpClient.cache(cache)
return httpClient.build()
}
}
in this way when a parameter of type OkHttpClient is needed, this function will return it
CodePudding user response:
How do you tell the Hilt
? With annotations. There is one REALLY good presentation from Jake Wharton on how Dependency injection works in Dagger2
(on which Hilt
is based on, so the idea is the same).
Most of what Dagger2/Hilt/DI is a Service Locator. Hilt
is a compile-time thing so it goes over all of your files with those annotations and takes note of what is provided where and what needs what and generates files that do all of that logic "under the hood".
Even in your example:
@HiltViewModel
class ExampleViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
private val repository: ExampleRepository
) : ViewModel() {
...
}
You tell Hilt
that ExampleViewModel
is a @HiltViewModel
. You also say that you want Hilt
to create it for you - with @Inject
- and you say that you want it to have two parameters savedStateHandle
and repository
. Now Hilt
will try to locate in your files if there is a ExampleRepository
with @Inject
or if some module @Provides
it explicitly.
class ExampleRepository @Inject constructor() {
...
}
or
@Module
@InstallIn(SingletonComponent::class)
object StorageModule {
@Provides
fun provideExampleRepository(): ExampleRepository = ExampleRepository()
}