android - 改造 http 缓存控制检查发回缓存,即使它已过时并再次进行网络调用

标签 android retrofit okhttp cache-control

我正在使用 Retrofit 1.9.+ 和 okhttp:2.2.+。

我想缓存我的回复。我用 Okclient 拦截器做了如下:

public abstract class RestController {
private static Context mContext;
private static long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MB

public static RestAdapter mRestAdapter;

public static void init(final Context context, String baseAPIUrl) {
    mContext = context;

    // Create Cache
    Cache cache = null;
    try {
        cache = new Cache(new File(mContext.getCacheDir(), "http"), SIZE_OF_CACHE);
    } catch (IOException e) {
        Log.e(RestController.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(baseAPIUrl)
            .setExecutors(executor, executor)
            .setClient(new OkClient(okHttpClient))
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();
}

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

        // Add Cache Control only for GET methods
        if (request.method().equals("GET")) {
            if (isNetworkAvailable()) {
                // 1 day
                request.newBuilder()
                        .header("Cache-Control", "only-if-cached")
                        .build();
            } else {
                // 4 weeks stale
                request.newBuilder()
                        .header("Cache-Control", "public, max-stale=2419200")
                        .build();
            }
        }

        Response response = chain.proceed(request);

        // Re-write response CC header to force use of cache
        return response.newBuilder()
                .header("Cache-Control", "public, max-age=86400") // 1 day
                .build();
    }
};

public static Boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if (networkInfo == null) {
        return false;
    }
    NetworkInfo.State network = networkInfo.getState();
    return (network == NetworkInfo.State.CONNECTED || network == NetworkInfo.State.CONNECTING);
}

现在我需要实现一个返回缓存的逻辑。我的缓存需要有两个指标: 1 fresh_upto 2 扔掉

那么逻辑是这样的 if(cache is present and current time <live upto){ send back cache } else if(current time<throwawaytime and current time >live upto){ send back cache make another network call onresponse send the new data back }

我如何通过缓存控制实现这一目标。我可以为此使用 max-age 或 max-stale 吗?

最佳答案

试试这个进行改造,它在我的项目中有效

@Headers("Cache-Control: max-age=" + (MINUTE)) @GET("your Url") Call<ResponseBody> getCourseStructureFromCache("Your Request paramater and all");

关于android - 改造 http 缓存控制检查发回缓存,即使它已过时并再次进行网络调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39389213/

相关文章:

java - 实现 Firebase (Flutter) 通知时,我收到错误

java - Android:如何使用 if 语句来获取 bundle/Intent 值?

Android Studio XML 自动完成功能无法正常工作

android - HttpLoggingInterceptor (OkHttp3) 为每个请求记录很多次

android - 使用 okHttp 信任所有证书

android - Dagger 2 Presenter 注入(inject)返回空值

android - 在 Retrofit 2.0 中使用 Mockito

android - 如何使用 Mockito 沿 Robospice 和 Retrofit 测试 API?

android - Retrofit 2示例教程但GsonConverterFactory显示错误 "Cannot resolve symbol"

java - okhttp 应用层 OkHttpClient 实例