PROBLEM
I need to call API from domains entered by USER and I need to edit my Retrofit
singleton before the call accordingly to the inserted data.
Is there a way to "reset" my singleton, forcing it to recreate?
or
Is there a way to update my baseUrl
with my data (maybe in Interceptor?) just before call?
CODE
Singletons
@Provides
@Singleton
Retrofit provideRetrofit(SharedPreferences prefs) {
String apiUrl = "https://%1s%2s";
apiUrl = String.format(apiUrl, prefs.getString(ACCOUNT_SUBDOMAIN, null), prefs.getString(ACCOUNT_DOMAIN, null));
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new HeaderInterceptor())
.build();
return new Retrofit.Builder()
.baseUrl(apiUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
@Provides
@Singleton
API provideAPI(Retrofit retrofit) {
return retrofit.create(API.class);
}
API
@FormUrlEncoded
@POST("endpoint")
Observable<Response> logIn(@Field("login") String login, @Field("password") String password);
How it works now
Well the idea was to save user domain data via SharedPrefs
before API call and modify baseUrl
with formatted String.
I see 2 options here:
baseUrl
their ownRetrofit
client, orDagger approach
If you were to brute force urls, this would probably not be the right choice, since it relies on creating a new
Retrofit
instance for each.Now every time the url changes, you just recreate the following demonstrated
UrlComponent
by supplying it with a newUrlModule
.Clean up
Clean your
@Singleton
module, so that it providesGsonConverterFactory
, andRxJavaCallAdapterFactory
to make proper use of dagger and not recreate shared objects.Url Scoped
Introduce a
@UrlScope
to scope yourRetrofit
instances.Then create a subcomponent
And a module for it
Use scoped
Retrofit
Instantiate the component and use it.
OkHttp approach
Provide a properly scoped interceptor (
@Singleton
in this case) and implement the corresponding logic.todo Implement the
MyApiInterceptor
. You will need to have a setter for the base url, and then just rewrite / modify the requests coming through.Then, again, just go ahead and use it.
As a third approach, you could also use reflection to just directly change base the base URL—I added this last just for completeness.
You can implement
BaseUrl
and pass that instead of a fixed URL.check out this link Other approach is implementingEndpoint
and make use ofsetUrl()
.So for changing some header value at run time then you can use interceptor and add it to OkHttp.