如何在 Hilt 中生成相同类型的对象?
How to generate objects with the same type in Hilt?
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
}
他们的区别只有baseUrl
.
我试图通过使用@Qualifier
来解决这个问题。
interface RetrofitQualifier {
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class Retrofit
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class MyRetrofit
}
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Singleton
@Provides
@RetrofitQualifier.Retrofit
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
@RetrofitQualifier.MyRetrofit
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
}
我在 class:
中使用 @RetrofitQualifier.MyRetrofit
class MyRepository @Inject constructor(
application: Application
) {
...
@Inject
@RetrofitQualifier.MyRetrofit
lateinit var retrofit:Retrofit
private val service: Service = retrofit.create(Service::class.java)
...
}
然而,我失败了,日志是
kotlin.UninitializedPropertyAccessException: lateinit property retrofit has not been initialized
我该怎么办?也许使用 @Named
?我不确定...
以 Qualifier
为例,您可以将其添加到您拥有提供商的同一文件中,甚至可以创建一个 RetrofitQualifier.kt
文件并将它们添加到那里。
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitOne
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitTwo
还有 @Provides
@Singleton
@Provides
@RetrofitOne
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
@RetrofitTwo
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
然后在你的Repository
中你可以使用两个选项进行注入
字段注入
// At field injection.
@AndroidEntryPoint
class MyRepository @Inject constructor(...) {
@RetrofitOne
@Inject lateinit var retrofit: Retrofit
}
作为依赖注入构造函数class
// As a dependency of a constructor-injected class.
class MyRepository @Inject constructor(
@RetrofitTwo private val retrofit: Retrofit
) : ...
但问题是,您可能将 installedIn 安装在您的存储库不可见的另一个模块中。
关于@Named
你仍然可以使用它但是根据文档建议使用Qualifier
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
}
他们的区别只有baseUrl
.
我试图通过使用@Qualifier
来解决这个问题。
interface RetrofitQualifier {
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class Retrofit
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class MyRetrofit
}
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Singleton
@Provides
@RetrofitQualifier.Retrofit
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
@RetrofitQualifier.MyRetrofit
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
}
我在 class:
中使用@RetrofitQualifier.MyRetrofit
class MyRepository @Inject constructor(
application: Application
) {
...
@Inject
@RetrofitQualifier.MyRetrofit
lateinit var retrofit:Retrofit
private val service: Service = retrofit.create(Service::class.java)
...
}
然而,我失败了,日志是
kotlin.UninitializedPropertyAccessException: lateinit property retrofit has not been initialized
我该怎么办?也许使用 @Named
?我不确定...
以 Qualifier
为例,您可以将其添加到您拥有提供商的同一文件中,甚至可以创建一个 RetrofitQualifier.kt
文件并将它们添加到那里。
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitOne
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitTwo
还有 @Provides
@Singleton
@Provides
@RetrofitOne
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
@RetrofitTwo
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
然后在你的Repository
中你可以使用两个选项进行注入
字段注入
// At field injection.
@AndroidEntryPoint
class MyRepository @Inject constructor(...) {
@RetrofitOne
@Inject lateinit var retrofit: Retrofit
}
作为依赖注入构造函数class
// As a dependency of a constructor-injected class.
class MyRepository @Inject constructor(
@RetrofitTwo private val retrofit: Retrofit
) : ...
但问题是,您可能将 installedIn 安装在您的存储库不可见的另一个模块中。
关于@Named
你仍然可以使用它但是根据文档建议使用Qualifier