2

I have Hilt DI framework in my Android project. Also I have retrofit, and ApiNetworkModule for getting singleton retrofit object:

@Module
@InstallIn(SingletonComponent.class)
public class ApiNetworkModule {
...
    @Singleton
    @Provides
    public Retrofit provideRetrofit(
            OkHttpClient okHttpClient,
            Gson gson,
            SharedPrefManager sharedPrefManager
    ) {
        return new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(sharedPrefManager.getUrl())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }
...
}

In general it works fine, but I have noticed in the case when url is updated in sharedPrefManager, retrofit object does not know about it and uses old url. It will be fully updated only after closing-opening application. Is there any way how to reinit Retrofit singleton programmatically? Or how to handle it correctly?

Alex D.
  • 1,424
  • 15
  • 40
  • Can you use application context to getUrl and create SharedPreference every time using that context? Then It will give updated baseurl. – Abdullah Javed Feb 15 '23 at 14:44
  • 1
    @AbdullahJaved no, it will not work. Retrofit object will be created only once and even when url will be changed in sharedPreferences, Retrofit will not be reinitialized. – Alex D. Feb 16 '23 at 09:19
  • I'm currently using it in my project to get the current app language from preferences for header. And it's working. – Abdullah Javed Feb 16 '23 at 12:02
  • Can you please attach the code, how it looks? Because in the code from my post, Retrofit object definitely will not be recreated – Alex D. Feb 22 '23 at 08:03

1 Answers1

-1

The way to receive the Retrofit object with the modified URL is to remove @Singleton . If you remove @Singleton, you can create a Retrofit object by applying the modified URL to sharedPreferences because a Retrofit object is created and injected when creating a repository.

@Module
@InstallIn(SingletonComponent.class)
public class ApiNetworkModule {
...
  
    @Provides
    public Retrofit provideRetrofit(
            OkHttpClient okHttpClient,
            Gson gson,
            SharedPrefManager sharedPrefManager
    ) {
        return new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(sharedPrefManager.getUrl())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }
...
}

We recommend this method because what you want is a way for a new object to be created and injected when there is a modified URL, rather than a Retrofit object that exists only in the singleton component dependency tree.