使用匕首柄作为依赖注入处理多个改造客户端?
Handle multiple retrofit client using dagger hilt as dependency injection?
我想在我的 android 应用程序中使用两个不同的后端,具有不同的响应格式,我使用 hilt 作为依赖注入,并对网络调用进行改造,这非常适合。
因为我已经添加了我的第二个服务器网络文件和应用程序模块,它给了我最后列出的错误。
我需要知道在这种情况下的出路,而不需要进行任何显着的架构更改。
@Keep
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun provideRetrofit(gson: Gson,@ApplicationContext appContext: Context): Retrofit = Retrofit.Builder()
.client(
OkHttpClient().newBuilder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).readTimeout(80,TimeUnit.SECONDS)
.addInterceptor(
ChuckerInterceptor.Builder(appContext)
.collector(ChuckerCollector(appContext))
.maxContentLength(250000L)
.redactHeaders(emptySet())
.alwaysReadResponseBody(false)
.build()
)
.build()
)
.baseUrl(UtilSingleton.instance!!.GetBaseUrl())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
@Provides
fun provideGson(): Gson = GsonBuilder().create()
@Provides
fun providePostsService(retrofit: Retrofit): ApiService =
retrofit.create(ApiService::class.java)
@Singleton
@Provides
fun provideApiRemoteDataSource(apiService: ApiService) = ApiRemoteDataSource(apiService)
@Singleton
@Provides
fun provideRepository(
remoteDataSource: ApiRemoteDataSource
) =
MainRepo(remoteDataSource)
/**----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------**/
@Singleton
@Provides
fun provideRetrofitEmall(gson: Gson,@ApplicationContext appContext: Context): Retrofit = Retrofit.Builder()
.client(
OkHttpClient().newBuilder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).readTimeout(80,TimeUnit.SECONDS)
.addInterceptor(
ChuckerInterceptor.Builder(appContext)
.collector(ChuckerCollector(appContext))
.maxContentLength(250000L)
.redactHeaders(emptySet())
.alwaysReadResponseBody(false)
.build()
)
.build()
)
.baseUrl(UtilSingleton.instance!!.GetBaseUrl())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
@Provides
fun providePostsServiceEmall(retrofit: Retrofit): EmallApiService =
retrofit.create(EmallApiService::class.java)
@Singleton
@Provides
fun provideApiRemoteDataSource(apiService: EmallApiService) = EmallApiRemoteDataSource(apiService)
@Singleton
@Provides
fun provideRepository(
remoteDataSource: EmallApiRemoteDataSource
) =
EmallRepo(remoteDataSource)
}
构建错误 ->
Execution failed for task ':app:kaptLocalDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
> java.lang.reflect.InvocationTargetException (no error message)
完整日志 ->
D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:40: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.remote.ApiRemoteDataSource provideApiRemoteDataSource(@org.jetbrains.annotations.NotNull()
^D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:78: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.remote.emallremote.EmallApiRemoteDataSource provideApiRemoteDataSource(@org.jetbrains.annotations.NotNull()
^D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:48: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.repository.MainRepo provideRepository(@org.jetbrains.annotations.NotNull()
^D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:86: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.repository.EmallRepo provideRepository(@org.jetbrains.annotations.NotNull()
^warning:
File for type 'com.uae.myvaultspay.MyApplication_HiltComponents' created
in the last round will not be subject to annotation processing.
Execution failed for task ':app:kaptLocalDebugKotlin'.
> A failure occurred while executing
org.jetbrains.kotlin.gradle.internal.KaptExecution
> java.lang.reflect.InvocationTargetException (no error message)
如果您想 return 使用 Dagger 或 Hilt 改造客户端,那么您应该使用 @Named
注释。此注释有助于 Hilt 或 Dagger 了解您使用相同的 Retrofit return 类型,您需要获取哪个 Retrofit 实例。
按照以下方式,您可以提供多个带有刀柄或匕首的改装实例。
首先,我在这里看到您提供了2个改造实例。为您提供的每个改造实例添加 @Named
注释。
object AppModule {
@Singleton
@Provides
@Named("Normal")
fun provideRetrofit(gson: Gson, @ApplicationContext appContext: Context): Retrofit = ...
@Singleton
@Provides
@Named("Email")
fun provideRetrofitEmall(gson: Gson, @ApplicationContext appContext: Context): Retrofit = ...
}
接下来,当您提供api服务时,指定给Hilt或Dagger需要哪个改造实例。
object AppModule {
@Provides
fun providePostsService(@Named("Normal") retrofit: Retrofit): ApiService = retrofit.create(ApiService::class.java)
@Provides
fun providePostsServiceEmall(@Named("Email") retrofit: Retrofit): EmallApiService = retrofit.create(EmallApiService::class.java)
}
最后,清理项目并重建项目以查看结果。
我想在我的 android 应用程序中使用两个不同的后端,具有不同的响应格式,我使用 hilt 作为依赖注入,并对网络调用进行改造,这非常适合。
因为我已经添加了我的第二个服务器网络文件和应用程序模块,它给了我最后列出的错误。
我需要知道在这种情况下的出路,而不需要进行任何显着的架构更改。
@Keep
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun provideRetrofit(gson: Gson,@ApplicationContext appContext: Context): Retrofit = Retrofit.Builder()
.client(
OkHttpClient().newBuilder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).readTimeout(80,TimeUnit.SECONDS)
.addInterceptor(
ChuckerInterceptor.Builder(appContext)
.collector(ChuckerCollector(appContext))
.maxContentLength(250000L)
.redactHeaders(emptySet())
.alwaysReadResponseBody(false)
.build()
)
.build()
)
.baseUrl(UtilSingleton.instance!!.GetBaseUrl())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
@Provides
fun provideGson(): Gson = GsonBuilder().create()
@Provides
fun providePostsService(retrofit: Retrofit): ApiService =
retrofit.create(ApiService::class.java)
@Singleton
@Provides
fun provideApiRemoteDataSource(apiService: ApiService) = ApiRemoteDataSource(apiService)
@Singleton
@Provides
fun provideRepository(
remoteDataSource: ApiRemoteDataSource
) =
MainRepo(remoteDataSource)
/**----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------**/
@Singleton
@Provides
fun provideRetrofitEmall(gson: Gson,@ApplicationContext appContext: Context): Retrofit = Retrofit.Builder()
.client(
OkHttpClient().newBuilder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).readTimeout(80,TimeUnit.SECONDS)
.addInterceptor(
ChuckerInterceptor.Builder(appContext)
.collector(ChuckerCollector(appContext))
.maxContentLength(250000L)
.redactHeaders(emptySet())
.alwaysReadResponseBody(false)
.build()
)
.build()
)
.baseUrl(UtilSingleton.instance!!.GetBaseUrl())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
@Provides
fun providePostsServiceEmall(retrofit: Retrofit): EmallApiService =
retrofit.create(EmallApiService::class.java)
@Singleton
@Provides
fun provideApiRemoteDataSource(apiService: EmallApiService) = EmallApiRemoteDataSource(apiService)
@Singleton
@Provides
fun provideRepository(
remoteDataSource: EmallApiRemoteDataSource
) =
EmallRepo(remoteDataSource)
}
构建错误 ->
Execution failed for task ':app:kaptLocalDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
> java.lang.reflect.InvocationTargetException (no error message)
完整日志 ->
D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:40: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.remote.ApiRemoteDataSource provideApiRemoteDataSource(@org.jetbrains.annotations.NotNull()
^D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:78: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.remote.emallremote.EmallApiRemoteDataSource provideApiRemoteDataSource(@org.jetbrains.annotations.NotNull()
^D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:48: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.repository.MainRepo provideRepository(@org.jetbrains.annotations.NotNull()
^D:\vaultsNew\vaultspaynewapis\app\build\tmp\kapt3\stubs\localDebug\com\uae\myvaultspay\di\AppModule.java:86: error: Cannot have more than one binding method with the same name in a single module
public final com.uae.myvaultspay.data.repository.EmallRepo provideRepository(@org.jetbrains.annotations.NotNull()
^warning:
File for type 'com.uae.myvaultspay.MyApplication_HiltComponents' created
in the last round will not be subject to annotation processing.
Execution failed for task ':app:kaptLocalDebugKotlin'.
> A failure occurred while executing
org.jetbrains.kotlin.gradle.internal.KaptExecution
> java.lang.reflect.InvocationTargetException (no error message)
如果您想 return 使用 Dagger 或 Hilt 改造客户端,那么您应该使用 @Named
注释。此注释有助于 Hilt 或 Dagger 了解您使用相同的 Retrofit return 类型,您需要获取哪个 Retrofit 实例。
按照以下方式,您可以提供多个带有刀柄或匕首的改装实例。
首先,我在这里看到您提供了2个改造实例。为您提供的每个改造实例添加 @Named
注释。
object AppModule {
@Singleton
@Provides
@Named("Normal")
fun provideRetrofit(gson: Gson, @ApplicationContext appContext: Context): Retrofit = ...
@Singleton
@Provides
@Named("Email")
fun provideRetrofitEmall(gson: Gson, @ApplicationContext appContext: Context): Retrofit = ...
}
接下来,当您提供api服务时,指定给Hilt或Dagger需要哪个改造实例。
object AppModule {
@Provides
fun providePostsService(@Named("Normal") retrofit: Retrofit): ApiService = retrofit.create(ApiService::class.java)
@Provides
fun providePostsServiceEmall(@Named("Email") retrofit: Retrofit): EmallApiService = retrofit.create(EmallApiService::class.java)
}
最后,清理项目并重建项目以查看结果。