如何解决使用 dagger2 和 MVVM 为两个不同的基本 URL 创建多个改造实例
我正在尝试使用 Dagger2 和 MVVM 为两个不同的基本 URL 实现多个改造实例。我已经浪费了大量时间来测试 SO 中提供的不同方法,但仍然无法弄清楚。我也创建了新的限定符并创建了一个新实例,但我的所有请求仍然使用第一个实例。这是我的实现。
限定符
@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class APIService1
@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class APIService2
AppModule 类
@AssistedModule
@Suppress("unused")
@Module(includes = [ViewModelModule::class,CoreDataModule::class,AssistedViewModelModule::class,AssistedInject_AppModule::class])
class AppModule {
@Singleton
@Provides
fun provideServices(
APIService1 okHttpClient: OkHttpClient,converterFactory: MoshiConverterFactory
) =
provideService(okHttpClient,converterFactory,MyApi::class.java)
@Singleton
@Provides
@APIService2
fun provideMicroServices(
APIService1 okHttpClient: OkHttpClient,converterFactory: MoshiConverterFactory
) =
provideMicroService(okHttpClient,MyApi::class.java)
@APIService1
@Provides
fun providePrivateOkHttpClient(upstreamClient: OkHttpClient): OkHttpClient {
return upstreamClient.newBuilder().build()
}
@Singleton
@Provides
fun provideRemoteDataSource(myApiService: MyApi) = RemoteDataSource(myApiService)
private fun createRetrofit(
okhttpClient: OkHttpClient,converterFactory: MoshiConverterFactory
): Retrofit {
Retrofit.Builder()
.baseUrl("https://example1.com/api/")
.client(okhttpClient)
.addConverterFactory(converterFactory)
.build()
}
private fun createMicroServiceRetrofit(
okhttpClient: OkHttpClient,converterFactory: MoshiConverterFactory
): Retrofit {
Retrofit.Builder()
.baseUrl("https://example2.com/api/")
.client(okhttpClient)
.addConverterFactory(converterFactory)
.build()
}
private fun <T> provideService(
okhttpClient: OkHttpClient,converterFactory: MoshiConverterFactory,clazz: Class<T>
): T {
return createRetrofit(okhttpClient,converterFactory).create(clazz)
}
private fun <T> provideMicroService(
okhttpClient: OkHttpClient,clazz: Class<T>
): T {
return createMicroServiceRetrofit(okhttpClient,converterFactory).create(clazz)
}
}
CoreDataModule 类
@Module
class CoreDataModule {
@Provides
fun provideOkHttpClient(): OkHttpClient {
val interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
val client = OkHttpClient().newBuilder()
.connectTimeout(15,TimeUnit.SECONDS)
.readTimeout(90,TimeUnit.SECONDS)
.writeTimeout(60,TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
return client.build()
}
@Provides
@Singleton
fun provideMoshi(): Moshi = Moshi.Builder().build()
@Provides
@Singleton
fun provideMoshiConverterFactory(): MoshiConverterFactory =
MoshiConverterFactory.create()
}
RemoteDataSource 类
@Keep
class RemoteDataSource @Inject constructor(private val service: MyApi) : BaseDataSource() {
suspend fun getOtp(data: String) = getResult { service.getOtp(data) }
suspend fun getData(data: String) = getResult { service.getData(data) }
}
BaseDataSource 类
abstract class BaseDataSource {
protected suspend fun <T> getResult(call: suspend () -> Response<T>): Result<T> {
val response = call()
if (response.isSuccessful) {
val body = response.body()
if (body != null) return Result.success(body)
}
return error(" ${response.code()} ${response.message()}")
}
}
MyApi 类
interface MyApi {
@POST("Register/Otp")
@FormUrlEncoded
suspend fun getOtp(@Field("data") data: String): Response<OtpResponse>
@POST("Home/Data")
@FormUrlEncoded
suspend fun getData(@Field("data") data: String): Response<DataResponse>
}
这就是我在 ViewModel 中使用它的方式
我的 ViewModle 之一
class OtpViewModel @Inject constructor(
private val remoteDataSource: RemoteDataSource
) :
ViewModel() {
fun getNewOtp() = liveData {
try {
emit(Resource.loading(data = null))
val response = remoteDataSource.getOtp(params))
emit(Resource.success(data = response))
} catch (e: Exception) {
emit(Resource.error(data = null,message = e.message ?: e.localizedMessage.orEmpty()))
}
}
解决方法
像这样创建 2 个注释:
@Qualifier
@Target(
AnnotationTarget.FUNCTION,AnnotationTarget.PROPERTY_GETTER,AnnotationTarget.PROPERTY_SETTER,AnnotationTarget.FIELD,AnnotationTarget.VALUE_PARAMETER
)
@Retention(AnnotationRetention.BINARY)
annotation class ApiService1
@Qualifier
@Target(
AnnotationTarget.FUNCTION,AnnotationTarget.VALUE_PARAMETER
)
@Retention(AnnotationRetention.BINARY)
annotation class ApiService2
更改您的提供商:
@Provides
@Singleton
@ApiService1
fun provideServices(....): MyApi {
return ...
}
@Provides
@Singleton
@ApiService2
fun provideMicroServices(....): MyApi {
return ...
}
然后在您的 Android 课程中您可以这样做:
class MyActivity : FragmentActivity() {
@Inject
@ApiService1
lateinit var retrofit1: MyApi
@Inject
@ApiService2
lateinit var retrofit2: MyApi
....
}
或在课堂上:
class Repository @Inject constructor (
@ApiService1 retrofit1: MyApi
) {
....
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。