2016-11-25 16 views
1

ネットワークが利用できないときに、オフラインブラウジングのキャッシュを有効にしようとしています。 不幸にも、何らかの形で動作しません。アプリをデバッグするときに、インターセプタやキャッシュにアクセスしています。オフラインキャッシュokhttp + retrofit not working

私は以下のコードで何かが間違っていると思います。

public class ApiHelper { 

    Context context; 
    private static final int TIMEOUT = 30; 
    private static final int WRITE_TIMEOUT = 30; 
    private static final int CONNECT_TIMEOUT = 10; 
    //private static final int CACHE_SIZE = 500 * 1024 * 1024; 
    private static final int CACHE_SIZE = 10 * 1024 * 1024; 

    public static final String baseUrl = "http://test.com/api-new/"; 

    public ApiHelper(Context context) { 
     this.context = context; 
    } 

    private boolean isNetworkAvailable(Context context) { 
     ConnectivityManager connectivityManager 
       = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 
     return activeNetworkInfo != null && activeNetworkInfo.isConnected(); 
    } 


    // Configure access cache when offline 
    private final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() { 
     @Override 
     public Response intercept(Chain chain) throws IOException { 
      Response originalResponse = chain.proceed(chain.request()); 
      if (isNetworkAvailable(context)) { 
       int maxAge = 60; // read from cache for 1 minute 
       return originalResponse.newBuilder() 
         .removeHeader("Pragma") 
         .header("Cache-Control", "public, max-age=" + maxAge) 
         .build(); 
      } else { 
       int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale 
       return originalResponse.newBuilder() 
         .removeHeader("Pragma") 
         .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) 
         .build(); 
      } 
     } 
    }; 


    private static OkHttpClient CLIENT = new OkHttpClient(); 

    File httpCacheDirectory = new File(context.getCacheDir(), "HttpCache"); 
    Cache cache = new Cache(httpCacheDirectory, CACHE_SIZE); 

    { 
     CLIENT = new OkHttpClient.Builder(). 
       connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS). 
       writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS). 
       readTimeout(TIMEOUT, TimeUnit.SECONDS). 
       authenticator(new Authenticator()). 
       addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR). 
       cache(cache). 
       addInterceptor(new Interceptor() { 
        @Override 
        public Response intercept(Chain chain) throws IOException { 
         Request request; 

         UserModel user = HelperFactory.getDatabaseHelper().getUserDao().getCurrentUser(); 
         if (user != null && user.getAccess_token() != null) 
          request = chain.request().newBuilder() 
            .addHeader("X-Auth-Token", user.getAccess_token()).build(); 
         else 
          request = chain.request().newBuilder().build(); 

         long t1 = System.nanoTime(); 
         Logger.debug(ApiHelper.class.getName(), String.format("Sending request %s on %s%n", 
           request.url(), chain.connection())); 

         UserModel currentUser = HelperFactory.getDatabaseHelper().getUserDao().getCurrentUser(); 
         if (currentUser != null) 
          Logger.debug(ApiHelper.class.getName(), "Sending request header " + request.headers().toString()); 

         if (request != null && request.body() != null && request.body().contentLength() > 0) { 
          Buffer buffer = new Buffer(); 
          request.body().writeTo(buffer); 
          String body = buffer.readUtf8(); 
          Logger.debug(ApiHelper.class.getName(), "Sending request body " + body); 
         } 

         Response response = chain.proceed(request); 
         String msg = response.body().string(); 

         long t2 = System.nanoTime(); 

         Logger.debug(ApiHelper.class.getName(), String.format("Received response %s in %.1fms%nResponse code:%s%nReceived data: %s", 
           response.request().url(), (t2 - t1)/1e6d, response.code(), msg)); 

         return response.newBuilder() 
           .body(ResponseBody.create(response.body().contentType(), msg)) 
           .headers(response.headers()) 
           .build(); 
        } 
       }).build(); 
    } 

    @NonNull 
    public static MyApplication getInstance() { 
     Retrofit rf = new Retrofit.Builder() 
       .baseUrl(baseUrl) 
       .addConverterFactory(GsonConverterFactory.create(new GsonBuilder() 
         .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC) 
         .create())) 
       .client(CLIENT) 
       .build(); 

     return rf.create(MyApplication.class); 
    } 


} 
+0

リンクを参照してください。http://stackoverflow.com/questions/23429046/can-retrofit-with-okhttp-use-cache-data-when-offline – Vadivel

+0

こんにちは、私はオプションがありません.setCache(キャッシュ) okhttpクライアント。 キャッシュ(キャッシュ)。 残りはあなたが言及したリンクに沿っていると思いますか? – Simon

+0

このビデオリンクを参照してくださいhttps://caster.io/episodes/retrofit-2-offline-cache/ – Vadivel

答えて

0

初期化ブロックは静的ではありませんが、決して実行されないようにこのオブジェクトのインスタンスを割り当てることはありません。静的メンバーCLIENTの初期化を意図しているようです。この初期化は最終的にContextに依存しているため、静的初期化ブロックに変換することはできません。 Contextパラメーターを使用する初期化メソッドに変換します。注:私はcachehttpCacheDirもローカル変数としてこのメ​​ソッドに移しました。それらが使用されていないとして、あなたはまた、あなたのコンストラクタとcontextデータメンバーを削除することができ

@NonNull 
public static MyApplication getInstance(Context context) { 
    initClient(context); 
    Retrofit rf = new Retrofit.Builder() 
      .baseUrl(baseUrl) 
      .addConverterFactory(GsonConverterFactory.create(new GsonBuilder() 
        .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC) 
        .create())) 
      .client(CLIENT) 
      .build(); 

    return rf.create(MyApplication.class); 
} 

-

private static boolean isNetworkAvailable(Context context) { 
     ConnectivityManager connectivityManager 
       = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 
     return activeNetworkInfo != null && activeNetworkInfo.isConnected(); 
} 

// Configure access cache when offline 
private static Interceptor getInterceptor(Context context) { 
    return new Interceptor() { 
    @Override 
    //.... 
    } 
} 

private static void initClient(Context context) { 
    httpCacheDirectory = File(context.getCacheDir(), "HttpCache"); 
    Cache cache = new Cache(httpCacheDirectory, CACHE_SIZE); 
    CLIENT = new OkHttpClient.Builder(). 
      connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS). 
      writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS). 
      readTimeout(TIMEOUT, TimeUnit.SECONDS). 
      authenticator(new Authenticator()). 
      addInterceptor(getInterceptor((context)). 
      cache(cache). 
      addInterceptor(new Interceptor() { 
       @Override 
       public Response intercept(Chain chain) throws IOException { 
        Request request; 

        UserModel user = HelperFactory.getDatabaseHelper().getUserDao().getCurrentUser(); 
        if (user != null && user.getAccess_token() != null) 
         request = chain.request().newBuilder() 
           .addHeader("X-Auth-Token", user.getAccess_token()).build(); 
        else 
         request = chain.request().newBuilder().build(); 

        long t1 = System.nanoTime(); 
        Logger.debug(ApiHelper.class.getName(), String.format("Sending request %s on %s%n", 
          request.url(), chain.connection())); 

        UserModel currentUser = HelperFactory.getDatabaseHelper().getUserDao().getCurrentUser(); 
        if (currentUser != null) 
         Logger.debug(ApiHelper.class.getName(), "Sending request header " + request.headers().toString()); 

        if (request != null && request.body() != null && request.body().contentLength() > 0) { 
         Buffer buffer = new Buffer(); 
         request.body().writeTo(buffer); 
         String body = buffer.readUtf8(); 
         Logger.debug(ApiHelper.class.getName(), "Sending request body " + body); 
        } 

        Response response = chain.proceed(request); 
        String msg = response.body().string(); 

        long t2 = System.nanoTime(); 

        Logger.debug(ApiHelper.class.getName(), String.format("Received response %s in %.1fms%nResponse code:%s%nReceived data: %s", 
          response.request().url(), (t2 - t1)/1e6d, response.code(), msg)); 

        return response.newBuilder() 
          .body(ResponseBody.create(response.body().contentType(), msg)) 
          .headers(response.headers()) 
          .build(); 
       } 
      }).build(); 
} 

その後もContextgetInstanceあなたに方法を取ると、その後initClientを呼び出す必要があります。

+0

返信iagreenのThxでは、インターセプタメソッド(REWRITE_CACHE_CONTROL_INTERCEPTOR)を静的にする必要があるため、コードに適合します。次に、IsNetworkAvailableメソッドもコンテキスト(context.getSystemService)を必要とするという問題に遭遇します – Simon

+0

はい。私はそれらを逃した。あなたは半静的/半静的ではない実装をしていました。あなたはそれをすべて一貫させる必要があります。 – iagreen

+0

if(isNetworkAvailable(context))このコンテキストも静的である必要があります。 – Simon