2015-11-03 50 views
2

我有一個要求,只要網絡可用就從API獲取數據,並且只有在沒有網絡時才從緩存中獲取數據。只有當沒有網絡可用時從緩存中取回

我正在使用下面的代碼來緩存數據,但問題是一旦我設置最大年齡。數據總是從緩存中挑選出來,我該如何處理?

public static <S> S createGetService(Context context, Class<S>  serviceClass) { 
    mContext = context; 

    // Create Cache 
    Cache cache = null; 
    try { 
     cache = new Cache(new File(mContext.getCacheDir(), S_CACHE_NAME), SIZE_OF_CACHE); 
    } catch (Exception e) { 
     Log.e(ServiceGenerator.class.getSimpleName(), "Could not create Cache!", e); 
    } 

    // Create OkHttpClient 
    OkHttpClient okHttpClient = new OkHttpClient(); 
    okHttpClient.setCache(cache); 
    okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS); 
    okHttpClient.setReadTimeout(30, TimeUnit.SECONDS); 

    // Add Cache-Control Interceptor 
    okHttpClient.networkInterceptors().add(mCacheControlInterceptor); 

    // Create Executor 
    Executor executor = Executors.newCachedThreadPool(); 

    mRestAdapter = new RestAdapter.Builder() 
      .setEndpoint(APIConstants.BASE_URL) 
      .setExecutors(executor, executor) 
      .setClient(new OkClient(okHttpClient)) 
      .setLogLevel(RestAdapter.LogLevel.FULL) 
      .build(); 
    return mRestAdapter.create(serviceClass); 
} 


private static final Interceptor mCacheControlInterceptor = new Interceptor() { 
    @Override 
    public Response intercept(Interceptor.Chain chain) throws IOException { 
     Request request = chain.request(); 

     request.cacheControl().noCache(); 

     // Add Cache Control only for GET methods 
     if (request.method().equals(S_GET)) { 
      if (Utility.isNetworkConnected(mContext)) { 
       // Return API Response 
       request.newBuilder() 
         .header(S_CACHE_CONTROL, "no-cache") 
         .build(); 

       Log.e("CACHE", "******************FETCHING FROM API CALL**********************"); 
      } else { 
       // Get Cached Response 
       request.newBuilder() 
         .header(S_CACHE_CONTROL, "public, only-if-cached, max-stale=" + Long.MAX_VALUE) 
         .build(); 

       Log.e("CACHE", "******************FETCHING FROM CACHE**********************"); 
      } 
     } 

     Response response = chain.proceed(request); 

     // Re-write response CC header to force use of cache 
     return response.newBuilder() 
       .header(S_CACHE_CONTROL, "public, max-age=" + Long.MAX_VALUE) // No Caching 
       .build(); 
    } 
}; 
+0

是否'isNetworkConnected'總是返回false? – nasch

回答

0

一旦數據被緩存,網絡攔截器就不會被調用。

okHttpClient.networkInterceptors().add(mCacheControlInterceptor); 

要強制API調用當網絡可用時,我設置的最大年齡爲0

private static final RequestInterceptor mRequestInterceptor = new RequestInterceptor() { 
    @Override 
    public void intercept(RequestFacade request) { 
     if (Utility.isNetworkConnected(mContext)) { 
      // If network is present reset the max age to 0 to make a API call 
      request.addHeader(S_CACHE_CONTROL, S_CACHE_HEADER_MAX_AGE + S_ZERO_AGE); 
     } 
    } 
}; 

public static <S> S createGetService(Context context, Class<S> serviceClass) { 
    mContext = context; 

    // Create Cache 
    Cache cache = null; 
    try { 
     cache = new Cache(new File(mContext.getCacheDir(), S_CACHE_NAME), SIZE_OF_CACHE); 
    } catch (Exception e) { 
     Log.e(TAG, "Could not create Cache!", e); 
    } 

    // Create OkHttpClient 
    OkHttpClient okHttpClient = new OkHttpClient(); 
    okHttpClient.setCache(cache); 
    okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS); 
    okHttpClient.setReadTimeout(30, TimeUnit.SECONDS); 

    // Add Network Interceptor - to save values to cache 
    okHttpClient.networkInterceptors().add(mCacheControlInterceptor); 

    // Create Executor 
    Executor executor = Executors.newCachedThreadPool(); 

    mRestAdapter = new RestAdapter.Builder() 
      .setEndpoint(APIConstants.BASE_URL) 
      .setExecutors(executor, executor) 
      .setClient(new OkClient(okHttpClient)) 
      .setLogLevel(RestAdapter.LogLevel.FULL) 
      .setRequestInterceptor(mRequestInterceptor) 
      .build(); 
    return mRestAdapter.create(serviceClass); 
} 

private static final RequestInterceptor mRequestInterceptor = new RequestInterceptor() { 
    @Override 
    public void intercept(RequestFacade request) { 
     if (Utility.isNetworkConnected(mContext)) { 
      // If network is present reset the max age to 0 to make a API call 
      request.addHeader(S_CACHE_CONTROL, S_CACHE_HEADER_MAX_AGE + S_ZERO_AGE); 
     } 
    } 
}; 

private static final Interceptor mCacheControlInterceptor = new Interceptor() { 
    @Override 
    public Response intercept(Interceptor.Chain chain) throws IOException { 
     Response response = chain.proceed(chain.request()); 
     // Re-write Cache header to max value , to be used when no network 
     return response.newBuilder() 
       .header(S_CACHE_CONTROL, S_CACHE_HEADER_MAX_AGE + Long.MAX_VALUE) 
       .build(); 
    } 
}; 
相關問題