2016-06-16 10 views
0

Retrofit2用のシングルトンインスタンスを作成しようとしていますが、問題なく動作します。しかし、私がダイナミックヘッダーにしたいと思ったらすぐに私はそうすることができません。Retrofit2シングルトンインスタンス

public class ApiManager { 


    public final static String BASE_URL = "URL"; 



    private static ApiManager instance =null; 
    private ApiModule apiModule; 

    public interface ApiModule { 


     @GET("exists") 
     Call<ServerStatus> checkExistsTeamName(@Path("teamName") String teamName); 


    } 


    private ApiManager(){ 
     final TimeZone tz = TimeZone.getDefault(); 
     OkHttpClient client = new OkHttpClient(); 
     HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
     interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 
     try { 
      client.interceptors().add(new Interceptor() { 
       @Override 
       public com.squareup.okhttp.Response intercept(Interceptor.Chain chain) throws 
         IOException { 

        Request original = chain.request(); 
        Request request = original.newBuilder() 
          .header("X-API-Version", "1") 
          .header("X-USER-TIMEZONE", tz.getID()) 
          .method(original.method(), original.body()) 
          .build(); 


        return chain.proceed(request); 

       } 
      }); 
     }catch (Exception e){ 

     } 
     client.interceptors().add(interceptor); 

     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(BASE_URL) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .client(client) 
       .build(); 

     apiModule = retrofit.create(ApiModule.class); 
    } 





    public static ApiManager getInstance() { 
     if(instance == null) { 
      instance = new ApiManager(); 
     } 
     return instance; 
    } 




    public ApiModule getService() { 
     return apiModule; 
    } 

    public ApiModule getService(String token){ 
     return apiModule; 
    } 




} 

その他のアクティビティでは、改造を呼び出すことができます。

ApiManager apiManager = ApiManager.getInstance(); apiManager.getService()。checkExistsTeamName( "parameters")

ここでうまくいきます。追加の動的ヘッダーを追加したい場合はどうすればいいですか?私はここにこだわっています

+0

余分な動的ヘッダーを追加することはどういう意味ですか?これらを 'original.newBuilder()'というコードに追加しようとしていますか? – ishmaelMakitla

+0

特定のAPI呼び出しに余分なヘッダーを追加することを意味しますか? – Emma

+0

はい私は特定のAPiに余分なヘッダーを追加することを意味します@Emm – Sutirth

答えて

1

あなたは何らかの依存性注入が必要です。このコードを試してください。サービスをご利用になる前に、

ApiManager.setHeaders(map of headers); 

とヘッダーの値をご連絡ください。空のマップまたはnullを使用して呼び出して、それらを除外します。改造documentation 1として

public class ApiManager { 


public final static String BASE_URL = "URL"; 



private static ApiManager instance =null; 
private ApiModule apiModule; 

public interface ApiModule { 


    @GET("exists") 
    Call<ServerStatus> checkExistsTeamName(@Path("teamName") String teamName); 


} 

private static Map<String, String> headers = new HashMap<>(); 

public static void setHeaders(Map<String, String> headers) { 
    ApiManager.headers = headers; 
} 

private ApiManager(){ 
    final TimeZone tz = TimeZone.getDefault(); 
    OkHttpClient client = new OkHttpClient(); 
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 
    try { 
     client.interceptors().add(new Interceptor() { 
      @Override 
      public Response intercept(Interceptor.Chain chain) throws 
        IOException { 

       Request original = chain.request(); 
       Request.Builder builder = original.newBuilder() 
         .header("X-API-Version", "1") 
         .header("X-USER-TIMEZONE", tz.getID()) 
         .method(original.method(), original.body()); 

       if(headers != null) { 
        for (Map.Entry<String, String> entry : headers.entrySet()) { 
         builder.header(entry.getKey(), entry.getValue()); 
        } 
       } 

       Request request = builder.build(); 

       return chain.proceed(request); 

      } 
     }); 
    }catch (Exception e){ 

    } 
    client.interceptors().add(interceptor); 

    Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl(BASE_URL) 
      .addConverterFactory(GsonConverterFactory.create()) 
      .client(client) 
      .build(); 

    apiModule = retrofit.create(ApiModule.class); 
} 





public static ApiManager getInstance() { 
    if(instance == null) { 
     instance = new ApiManager(); 
    } 
    return instance; 
} 




public ApiModule getService() { 
    return apiModule; 
} 

public ApiModule getService(String token){ 
    return apiModule; 
} 

}

+0

でも、@svatOplukというヘッダー機能は必要ですか? – Sutirth

+0

あなたのやり方を試してみましたが、私にとってはうまくいかず、アプリケーションがクラッシュします。 – Sutirth

0

あなたが特定の要求にヘッダを追加したい場合は、以下のように行うことができます。

@Headersアノテーションを使用して、メソッドの静的ヘッダーを設定できます。

@Headers("Cache-Control: max-age=640000") 
@GET("widget/list") 
Call<List<Widget>> widgetList(); 

@Headers({ 
    "Accept: application/vnd.github.v3.full+json", 
    "User-Agent: Retrofit-Sample-App" 
}) 
@GET("users/{username}") 
Call<User> getUser(@Path("username") String username); 

ヘッダーはお互いに上書きされません。同じ名前の のヘッダーはすべてリクエストに含まれます。

リクエストヘッダーは@Header 注釈を使用して動的に更新できます。対応するパラメータを@Headerに提供する必要があります。 値がNULLの場合、ヘッダーは省略されます。それ以外の場合は、値に対してtoString が呼び出され、結果が使用されます。すべてのリクエストに追加する必要が

@GET("user") 
Call<User> getUser(@Header("Authorization") String authorization) 

ヘッダは OkHttp interceptorを使用して指定することができます。

+1

FYI、2.1.0以降複数の動的ヘッダパラメータがある場合、HeaderMapアノテーションが追加されています。 https://github.com/square/retrofit/blob/master/CHANGELOG.md#version-210-2016-06-15 – Emma

+1

@ Jickson、@ Emmaこれは私がそれぞれのリクエストごとにヘッダを書かなければならないという目的を解決しません面倒なことだと私は正しい方法ではないと思います。 – Sutirth

+0

複数のリクエストに対して同じヘッダを使用する場合は、OkHttpインターセプタを使用する必要があります。これを参照してくださいhttps://futurestud.io/blog/retrofit-add-custom-request-header – Jickson

関連する問題