通过为 Mockwebserver 提供基础 url 来解决错误

Hilt error by providing base url for Mockwebserver

在我的应用程序中,我使用 Hilt 进行依赖注入。我实现了一个 RetrofitModule 以在我的存储库中为其提供依赖项,如下所示:

@Module
@InstallIn(ApplicationComponent::class)
object RetrofitModule {

    @Singleton
    @Provides
    fun providesRetrofitClient(okHttpClient: OkHttpClient, baseUrl: String): Retrofit {
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()
    }

    @Provides
    fun providesBaseUrl(application: MyApplication): String {
        return application.getBaseUrl()
    }

    @Singleton
    @Provides
    fun providesOkHttpClient(): OkHttpClient {
        val okHttpClientBuilder = OkHttpClient.Builder()
        val loggingInterceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }
        okHttpClientBuilder.addInterceptor(loggingInterceptor)
        return okHttpClientBuilder.build()
    }

    @Singleton
    @Provides
    fun providesService(retrofit: Retrofit): MyService {
        return retrofit.create(MyService::class.java)
    }
}

为测试中的 Mockwebserver 配置提供测试基础 url 我在 MyApplicationMyApplicationTest class

中实现了函数

MyApplication.class

class MyApplication : Application() {
    fun getBaseUrl() = "https://www.foo-production.com"
}

MyApplicationTest.class

class MyApplicationTest : Application() {
    fun getBaseUrl() = "http://127.0.0.1:8080"
}

但是当我构建应用程序时出现此错误:

 A binding with matching key exists in component: de.xxx.xxx.MyApplication_HiltComponents.ApplicationC
      ...

我觉得是这个方法的问题

@Provides
fun providesBaseUrl(application: MyApplication): String {
    return application.getBaseUrl()
}

提供 MyApplication 时出现问题 class

A) 可能解决你的问题

Hilt 无法提供您的确切 MyApplication 实例,它只能提供通用 Application 实例(请参阅 Hilt Components 中的 Component default bindings)。

这应该可以解决问题:

@Provides
fun providesBaseUrl(application: Application): String {
    return (application as MyApplication).getBaseUrl()
}

也就是说,有一种更优雅的方式来实现它。

B) 优雅的方式

  1. src/main/your/package/中创建一个UrlModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object UrlModule {

    @Provides
    fun providesBaseUrl(application: MyApplication): String {
        return "https://www.foo-production.com"
    }

}
  1. src/test/your/package/(或 src/androidTest/your/package/,如果它用于 UI 测试)创建另一个 UrlModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object UrlModule {

    @Provides
    fun providesBaseUrl(application: MyApplication): String {
        return "http://127.0.0.1:8080"
    }

}