仅在没有可用网络时从缓存中获取

时间:2015-11-03 12:57:24

标签: android okhttp

我需要在网络可用时从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();
    }
};

1 个答案:

答案 0 :(得分:0)

缓存数据后不会调用网络拦截器。

okHttpClient.networkInterceptors().add(mCacheControlInterceptor); 

要在网络可用时强制执行A​​PI调用,我将max-age设置为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();
    }
};