在Hilt的文档中,它显示了将视图模型注入活动的示例:
@HiltViewModel
class ExampleViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
private val repository: ExampleRepository
) : ViewModel() {
...
}
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
private val exampleViewModel: ExampleViewModel by viewModels()
...
}
但是,如果ExampleRepository本身有一个需要参数的构造函数,该怎么办?活动中的代码有何不同?如何告诉Hilt要将哪些参数传递给Repository?
有多种方法,但我会提到我使用的一种用于来自自定义类型的参数,如改装api服务或OKHttp你需要像下面的一样提供它
@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
如何告诉Hilt
?带有注释。Jake Wharton就依赖注入如何在Dagger2
中工作做了一个非常好的演示(Hilt
是基于它的,所以想法是一样的(。
Dagger2/Hilt/DI的大部分内容都是服务定位器。Hilt
是一个编译时的东西,所以它会遍历所有带有这些注释的文件,并记录在哪里提供了什么以及需要什么,并生成执行所有逻辑的文件";在引擎盖下";。
即使在你的例子中:
@HiltViewModel
class ExampleViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
private val repository: ExampleRepository
) : ViewModel() {
...
}
您告诉Hilt
,ExampleViewModel
是@HiltViewModel
。你还说你希望Hilt
为你创建它——用@Inject
——你说你希望它有两个参数savedStateHandle
和repository
。现在,如果有@Inject
的ExampleRepository
,或者某个模块@Provides
显式存在,Hilt
将尝试在您的文件中进行定位。
class ExampleRepository @Inject constructor() {
...
}
或
@Module
@InstallIn(SingletonComponent::class)
object StorageModule {
@Provides
fun provideExampleRepository(): ExampleRepository = ExampleRepository()
}