具有Retrofit 2 Cache-Control的离线模式

时间:2018-06-08 06:16:35

标签: android retrofit2 cache-control offline-caching

我正在开发一个需要离线模式的Android应用程序,我正在使用带有缓存控制的改造2,但是面临的问题是缓存文件没有被创建,只有该文件夹中创建的文件被命名为journal.I am在这里发布我的ApiClient.java文件代码。

public class ApiClient {

public static final String BASE_URL = "http://www.something.com/";
private static Retrofit retrofit = null;
private static APIInterfaces apiInterface;
private  static Context mcontext=getApplicationContext();


static Interceptor OFFLINE_INTERCEPTOR = new Interceptor() {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (!isConnected()) {
            int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
            request = request.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }

        return chain.proceed(request);
    }
};


static Interceptor ONLINE_INTERCEPTOR = new Interceptor() {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        okhttp3.Response response = chain.proceed(chain.request());
        int maxAge = 60; // read from cache
        return response.newBuilder()
                .header("Cache-Control", "public, max-age=" + maxAge)
                .build();
    }
};



protected static Retrofit getClient() {
    if (retrofit == null) {

        createFolder();
        Gson gson = new GsonBuilder()
                .setLenient()
                .create();


        OkHttpClient okHttpClient = new OkHttpClient
                .Builder()
                .cache(new Cache(new File(Environment.getExternalStorageDirectory() + File.separator + "something"), 10 * 1024 * 1024)) // 10 MB
                .addInterceptor(OFFLINE_INTERCEPTOR)
                .addNetworkInterceptor(ONLINE_INTERCEPTOR)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL).client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }
    return retrofit;
}


public static APIInterfaces getApiInterface() {
    if (apiInterface == null)
        apiInterface = ApiClient.getClient().create(APIInterfaces.class);
    return apiInterface;
}



private static boolean isConnected() {
    try {
        android.net.ConnectivityManager e = (android.net.ConnectivityManager) mcontext.getSystemService(
                Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = e.getActiveNetworkInfo();
        return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    } catch (Exception e) {
        Log.w(TAG, e.toString());
    }

    return false;
}

public  static boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (mcontext.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            ActivityCompat.requestPermissions((Activity) mcontext,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        return true;
    }
}



private static void createFolder() {
    if (isStoragePermissionGranted()) {
        File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "Something");

        if (!folder.exists()) {
            folder.mkdir();
        }
    }
}

}

任何人都可以解释上面代码的问题。

1 个答案:

答案 0 :(得分:0)

使用拦截器更改标题时,在调用CacheStrategy.isCacheable()之前不会进行任何调整。

尝试使用interceptors()电话更改networkInterceptors()

看看这里: https://github.com/square/okhttp/wiki/Interceptors

此外,您无法使用OkHttp的缓存来缓存POST请求。您需要使用其他机制see this

来存储它们

其他机制:

有几种方法,一种可以将在线结果存储到本地数据库并在离线状态下从大多数人那里检索,第二种选择是覆盖OKHTTP,但这对移动设备来说代价很高设备在性能优于效益方面,第三个显然是将您的POST API结构转换为GET

但是,看看here它也包含一篇博客文章,它将对您有所帮助。