简体   繁体   English

带有Retrofit 2缓存控制的离线模式

[英]Offline mode with Retrofit 2 Cache-Control

I am working on a android app which has requirement of offline mode , I am using retrofit 2 with cache control , but facing problem that cache files are not getting created and only file is created in that folder is named journal.I am posting my ApiClient.java file code here. 我正在开发一个需要脱机模式的android应用程序,正在使用具有缓存控制功能的翻新2,但面临的问题是缓存文件未创建,并且仅在该文件夹中创建的文件名为journal。我正在发布我的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();
        }
    }
}

} }

Can anyone please explain what is problem with above code. 任何人都可以解释上面的代码有什么问题。

When you use interceptors to change headers it does not make any adjustments before CacheStrategy.isCacheable() is called. 使用拦截器更改标头时,在CacheStrategy.isCacheable()之前,它不会进行任何调整。

Try changing interceptors() with networkInterceptors() call. 尝试通过networkInterceptors()调用来更改interceptors()

Have a look here: https://github.com/square/okhttp/wiki/Interceptors 在这里看看: https : //github.com/square/okhttp/wiki/Interceptors

Also, you can't cache POST requests with OkHttp's cache. 同样,您不能使用OkHttp的缓存来缓存POST请求。 You'll need to store them using some other mechanism, see this 您需要使用其他某种机制来存储它们, 请参见

Other mechanisms: 其他机制:

There are several methods, one can be storing the online results to a local database and retrieve it from there if offline which most people do, the second option is to override OKHTTP but that will be costly for a mobile device in terms of performance over benefit, the third one is obviously converting your POST API structure to GET 有几种方法,一种可以将在线结果存储到本地数据库,如果大多数人离线则可以从那里检索它,第二种方法是覆盖OKHTTP但是对于移动设备而言,性能比收益高昂,第三个显然是将您的POST API结构转换为GET

But, have a look here it contains a blog article too, which will help you. 但是, 这里也有一篇博客文章,这对您有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM