2016-04-14 4 views
2

Ich habe eine App, die an mehreren Kunden auf verschiedenen Websites bereitgestellt wird. Es verwendet RetroFit, um mit dem Serverprodukt zu kommunizieren.Konfigurieren Sie RetroFit BASE URL in den Einstellungen

Das Problem ist, dass jeder Kunde dieses Serverprodukt auf seinem eigenen lokalen Server mit seiner eigenen BASE_URL bereitstellen wird, so dass die BASE_URL nicht fest in die App codiert werden kann. Es muss pro Gerät konfiguriert werden, wenn die App vor Ort bereitgestellt wird, statt dass die App für jeden Kunden erstellt wird.

Ich habe einen Einstellungsbildschirm mit einem Feld erstellt, um die BASE_URL zu bearbeiten und in SharedPreferences zu speichern. Meine Frage ist das: Ist es möglich, die BASE_URL mit diesem Wert von SharedPreferences auf jedem Call zu ersetzen?

Eigentlich muss es nicht SharedPreferences sein. Ich muss nur in der Lage sein, die BASE_URL zu konfigurieren und sie überall zu speichern. Sogar das Speichern einer Datei auf der SD-Karte reicht möglicherweise aus.

Hat jemand irgendwelche Vorschläge? Danke.

UPDATE: Hier ist mein Client-Code:

public class RestClient { 
    private static RestInterface REST_CLIENT; 
    private static final String API_BASE_URL = "http://myurl/"; 

    static { 
     setupRestClient(); 
    } 

    private RestClient() { 
    } 

    public static RestInterface get() { 
     return REST_CLIENT; 
    } 

    private static void setupRestClient() { 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(API_BASE_URL) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     REST_CLIENT = retrofit.create(RestInterface.class); 
    } 
} 

Dank.

+1

Wie in der Dokumentation beschrieben wird die URL in der Regel in der 'Retrofit.Builder' Klasse mit der Methode' baseUrl (String baseUrl) 'eingestellt werden. Es ist völlig in Ordnung, die URL der 'SharedPreferences' zu lesen. Berücksichtigen Sie die falsche Handhabung der URL. Also, was ist dein Problem? – momo

+0

Ich werde mit meinem Code aktualisieren und Sie werden das Problem sehen. Ich erstelle den 'Retrofit' Client statisch. Ich habe also keinen Zugriff auf "Kontext". – eoinzy

+1

Werfen Sie einen Blick auf https://gist.github.com/laaptu/feb3cae85f07c0c5fe3e und http://stackoverflow.com/questions/27816507/retrofit-multiple-endpoints-with-same-restadapter/27816635#27816635 – momo

Antwort

1

Hier ist die Lösung, die ich zu mir kam:

public class RestClient { 
    private static RestInterface REST_CLIENT; 
    private static final String API_BASE_URL = "http://myurl/"; 

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); 

    public static RestInterface get(@NonNull Context context) { 
     if (null == REST_CLIENT) { 
      setupRestClient(context); 
     } 
     return REST_CLIENT; 
    } 

    private static void setupRestClient(@NonNull Context context) { 

     String baseUrl = CustomPrefs.getInstance(context).getEndpointBaseUrl(); 
     httpClient.addInterceptor(getInterceptorWithAuth(context)); 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(baseUrl) 
       .client(httpClient.build()) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     REST_CLIENT = retrofit.create(RestInterface.class); 
    } 

    private static Interceptor getInterceptorWithAuth(@NonNull final Context context) { 
     final String username = CustomPrefs.getInstance(context).getHttpUsername(); 
     final String password = CustomPrefs.getInstance(context).getHttpPassword(); 
     final String credentials = username + ":" + password; 
     final String basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); 

     return new Interceptor() { 
      @Override 
      public Response intercept(Interceptor.Chain chain) throws IOException { 
       Request original = chain.request(); 

       Request.Builder requestBuilder = original.newBuilder() 
         .header("Authorization", basic) 
         .header("Accept", "application/json") 
         .header("User-Agent", "myApp") 
         .method(original.method(), original.body()); 

       Request request = requestBuilder.build(); 
       return chain.proceed(request); 
      } 
     }; 
    } 
} 

ich auch in HTTP Basic Auth hinzugefügt. Entfernen Sie httpClient und die getInterceptorWithAuth() Methode, wenn Sie Auth nicht benötigen.

ANWENDUNG:

call = RestClient.get(context).whateverMethod();