2016-08-08 4 views
3

さて、私はRetrofitを使用することで迷っています...まず、Retrofitインスタンスによって作成されたサービスインスタンスを保持するSingletonヘルパークラスを作成します。サービスを取得してHTTPリクエストを行うのは非常に便利ですが、ヘルパーインスタンスが静的であるため、SharedPreferencesからアクセストークンを取得できないことがわかります。 Authenticatorインターフェイスを使用して認証を処理するため、要求時にアクセストークンを渡すことはできません。私はアプリケーションクラスを拡張し、静的フィールドでアプリケーションインスタンスを保持しようとするが、Android Studioは私に警告を与える(Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run))。1つのグローバルRetrofitインスタンスを使用するか、Androidでリクエストごとに1つ作成する必要がありますか?

これで、別の選択肢があります:各リクエストに対して、アクセストークンを受け入れ、Retrofitインスタンスを構築し、サービスインスタンスを作成し、要求を行う静的ヘルパーメソッドを作成します。今私はこれがベストプラクティスかどうかを混乱させています。 1つのサービスインスタンスの再利用と各リクエストのサービスの作成の違いは何ですか?

PS:上記のserviceという単語は、ではなく、someRetrofit.create(someServiceInterface.class)によって作成されたサービスインスタンスを指します。

+0

私のプロジェクトでは、メモリリークについてのこの警告は表示されません。しかし、とにかく、それは唯一の警告です。アプリケーションへの静的な参照を保持するのに間違ったことはありません。私はそれについてここで答えているhttp://stackoverflow.com/questions/14057273/android-singleton-with-global-context/14057777#14057777。だから私の提案は、単一のアプリケーションを使用することであり、この警告について心配する必要はありません。 – Budius

+0

@Budius実際には、 'someRetrofit.create(xxx.class) 'によって作成された単一インスタンスを再利用して、各リクエストでこれを行うことの違いを知りたいと思っています。 – Perqin

+0

私はそれほど深く掘り下げることはありませんが、インスタンスはスレッド、コールバック、インターセプタを制御/保持しているようですので、毎回新しいスレッドを作成するべきではないはずです。 – Budius

答えて

0

私はまた、将来の設計からもその良い点として、シングルトンアプローチだけをお勧めします。

複数のインスタンスのサービスを作成すると、それぞれがreadTimeout、writeTimeout、response logging propertyなどの異なるネットワークプロパティを持つ可能性があります。これらをすべて単一のプロパティに設定する必要があります。あなたに頭痛の多くを与えます。

私が直面したユーザケースは、後で、あなたのバックエンドチームが、デバイスのバージョンのようなリクエストごとに追加のヘッダパラメータを追加して、このプロパティをすべてのretrofitクライアントに追加する必要がありました。痛みである。

ここに私のコードのスニペット、どのように私はヘッダーを処理します。

public static Retrofit getRestAdapter(final HashMap<String, String> requestHeaderMap) { 
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 
    OkHttpClient client = new OkHttpClient.Builder() 
      .addInterceptor(interceptor) 
      .addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR) 
      .addNetworkInterceptor(new Interceptor() { 
       @Override 
       public Response intercept(Chain chain) throws IOException { 
        Request.Builder builder = chain.request().newBuilder(); 
        Set<Map.Entry<String, String>> entrySet = requestHeaderMap.entrySet(); 
        for (Map.Entry<String, String> entry : entrySet) { 
         if (entry.getValue().isEmpty()) 
          builder.removeHeader(entry.getKey()); 
         else 
          builder.addHeader(entry.getKey(), entry.getValue()); 
        } 

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


      }).build(); 

    return new Retrofit.Builder() 
      .baseUrl(Constants.BASE_URL) 
      .client(client) 
      .addConverterFactory(GsonConverterFactory.create()) 
      .build(); 
} 

また、requestHeaderMapのインスタンスはグローバルインスタンスであり、データはobservableパターンを使用してプッシュされています。

私はこれがあなたの決定に役立つことを望みます。

関連する問題