Reputation: 595
I'm using retrofit & Dagger2 for my application.I want to change the baseUrl of an application dynamically based on the what user selects in the Spinner.
After spending couple of hours on internet i came to conclusion that it is possible to change the baseUrl dynamically.
The Dependency Injection looks like this:
APiModule
@Module
public class ApiModule {
String mBaseUrl;
public ApiModule(String mBaseUrl) {
this.mBaseUrl = mBaseUrl;
}
@Provides
@Singleton
OkHttpClient provideOkhttpClient(Cache cache) {
OkHttpClient.Builder client = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
client.addInterceptor(logging);
client.cache(cache);
return client.build();
}
@Provides
@Singleton
Retrofit provideRetrofit(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(mBaseUrl)
.client(okHttpClient)
.build();
}
}
I have created one extra class as per the reference from internet
HostSelectionInterceptor.java
import java.io.IOException;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
/** An interceptor that allows runtime changes to the URL hostname. */
@Module(includes = {ApiModule.class})
public final class HostSelectionInterceptor implements Interceptor {
private volatile String host;
@Provides
@Singleton
public String setHost(String host) {
this.host = host;
return this.host;
}
public String getHost() {
return host;
}
@Provides
@Singleton
@Override
public okhttp3.Response intercept(Chain chain) {
Request request = chain.request();
String host = getHost();
if (host != null) {
/* HttpUrl newUrl = request.url().newBuilder()
.host(host)
.build();*/
HttpUrl newUrl = HttpUrl.parse(host);
request = request.newBuilder()
.url(newUrl)
.build();
}
try {
return chain.proceed(request);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Now, my question is how i can use HostSelectionInterceptor to change my baseUrl on changing the Spinner.
Upvotes: 0
Views: 4438
Reputation: 2884
You can use @Named
(or custom annotations that are annotated with @Qualifier)
Add the annotations like the following:
@Singleton
@Provides
@Named("picture")
Retrofit providePictureRetrofit(GsonConverterFactory gsonConverterFactory, RxJavaCallAdapterFactory rxJavaCallAdapterFactory) {
return retrofit = new Retrofit.Builder()
.baseUrl(MarsWeatherWidget.PICTURE_URL) // one url
.build();
}
@Singleton
@Provides
@Named("weather")
Retrofit provideWeatherRetrofit(GsonConverterFactory gsonConverterFactory, RxJavaCallAdapterFactory rxJavaCallAdapterFactory) {
return retrofit = new Retrofit.Builder()
.baseUrl(MarsWeatherWidget.WEATHER_URL) // other url
.build();
}
Injecting the qualified version
When you have your module providing the qualified types, you just need to also add the qualifier where you need the dependency.
MyPictureService provideService(@Named("picture") Retrofit retrofit) {
// ...
}
Upvotes: 3
Reputation: 147
Request.Builder.url - is a request URL. So it's everything that is added to Base_URL.
To dynamically change the base url, you have to recreate retrofit object.
Checkout the Mock Server I've been working on: https://github.com/macieknajbar/MockServer/blob/master/app/src/main/java/com/example/mockserver/rest/server/MockServer.kt
Run tests and make changes for your own use (to replace base url, not only responses).
Upvotes: 0