12
@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()
    }
}

Their difference is only baseUrl.


I tried to solve this problem by use @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()
    }
}

And I use it by use @RetrofitQualifier.MyRetrofit in my class:

class MyRepository @Inject constructor(
    application: Application
)  {

    ...    

    @Inject
    @RetrofitQualifier.MyRetrofit
    lateinit var  retrofit:Retrofit


    private val service: Service = retrofit.create(Service::class.java)

    ...

    }

However, I was failed, the log is

kotlin.UninitializedPropertyAccessException: lateinit property retrofit has not been initialized

What should I do? Maybe use @Named? I am not sure...

pnkj
  • 406
  • 5
  • 17

1 Answers1

22

Example with Qualifier, you can add this in the same file where you have your providers or even create a RetrofitQualifier.kt file and add them there.

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitOne

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitTwo

And the @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()
}

Then in your Repository you can inject using two options

Field injection

// At field injection.
@AndroidEntryPoint
class MyRepository @Inject constructor(...) {

  @RetrofitOne
  @Inject lateinit var retrofit: Retrofit
}

As a dependency injected-constructor class

// As a dependency of a constructor-injected class.
class MyRepository @Inject constructor(
  @RetrofitTwo private val retrofit: Retrofit
) : ...

But the thing is that perhaps you installedIn in another module where your Repository doesn't have visibility.

About the @Named you can still use it but as per the documentation is recommended to use Qualifier

Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148
  • Ok, I will add my @InstallIn immediately – pnkj Jul 30 '21 at 08:18
  • Could it be another reason? Because when I have only one `Retrofit` and no `MyRetrofit`, it can run successfully. – pnkj Jul 30 '21 at 08:22
  • 1
    Could you try using the inject-constructor way? – Skizo-ozᴉʞS ツ Jul 30 '21 at 08:23
  • It's amazing. I succeeded! Why is that? Maybe you can feed this bug back to Google official? But I don't know how to operate. Thank you, you have helped me several times, thank you! – pnkj Jul 30 '21 at 08:31
  • @Skizo-ozᴉʞS . I also face with is problem and I found this question. But I cant solve. Can you please help me SIR. this is my question. https://stackoverflow.com/questions/71121237/dagger-missing-binding-with-same-type-of-datastore – KyawLinnThant Feb 15 '22 at 05:42