2017-08-18 5 views
0

J'utilise retrofit & Dagger2 pour mon application. Je veux changer le baseUrl d'une application dynamiquement en fonction de ce que l'utilisateur sélectionne dans le Spinner. Après avoir passé quelques heures sur internet, je suis arrivé à la conclusion qu'il est possible de changer dynamiquement le fichier baseUrl.Changement de baseUrl dynamiquement en utilisant rétrofit & dagger2

L'injection de dépendance ressemble à ceci:

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(); 
    } 
} 

J'ai créé une classe supplémentaire selon la référence à partir d'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; 
    } 
} 

Maintenant, ma question est comment je peux utiliser HostSelectionInterceptor pour changer mon baseUrl sur le changement du Spinner.

+2

double possible de [URL dynamique Dague + Rénovation] (https://stackoverflow.com/questions/36769923/dagger-retrofit-dynamic-url) –

Répondre

1

Request.Builder.url - est une URL de demande. C'est donc tout ce qui est ajouté à Base_URL.

Pour modifier dynamiquement l'URL de base, vous devez recréer l'objet retrofit.

Commander le serveur Mock je travaille sur: https://github.com/macieknajbar/MockServer/blob/master/app/src/main/java/com/example/mockserver/rest/server/MockServer.kt

Exécution de tests et faire des changements pour votre propre usage (pour remplacer url de base, non seulement des réponses).

1

Vous pouvez utiliser @Named (ou des annotations personnalisées qui sont annotés avec @Qualifier) ​​ Ajouter les annotations comme les suivantes:

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

Injecter la version qualifiée

Lorsque vous avez votre module fournissant les types qualifiés, vous devez simplement ajouter le qualificateur où vous avez besoin de la dépendance.

MyPictureService provideService(@Named("picture") Retrofit retrofit) { 
    // ... 
}