retrofit实现缓存 需要结合okhttp实现 其中需要实现拦截器,缓存大小,缓存目录,缓存时间,网络状态,
import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.util.Log; import android.util.SparseArray; import com.dream.will.hydrogenballoon.MyApp; import com.dream.will.hydrogenballoon.utils.NetWorkUtil; import java.io.File; import java.io.IOException; import java.util.concurrent.TimeUnit; import okhttp3.Cache; import okhttp3.CacheControl; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; /** * Created by Karlo on 2016/12/20. */ public class RetrofitManager { private static final int MAX_AGE = 60 * 60; private static final int MAX_STALE = 60 * 60 * 24; private static final String CACHE_STALE = "public ,only if cached max-stale=" + MAX_STALE; private static final String CACHE_AGE = "public ,max-age=" + MAX_AGE; private static SparseArray<Retrofit> retrofitList = new SparseArray<>(); private static OkHttpClient client; public static Retrofit getInstance(int type) { Retrofit retrofit = retrofitList.get(type); if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(ApiConstant.getHostByType(type)) .addConverterFactory(GsonConverterFactory.create()) .client(getOkHttpInstance()) .build(); retrofitList.put(type, retrofit); } return retrofit; } private static OkHttpClient getOkHttpInstance() { if (null == client) { synchronized (RetrofitManager.class) { if (null == client) { File file = new File(MyApp.getInstance().getExternalCacheDir(), "okHttp"); client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .addInterceptor(new CacheControlIntercepter()) .addNetworkInterceptor(new CacheControlIntercepter()) .addInterceptor(new LogIntercepter()) .cache(new Cache(file, 10 * 1024 * 1024)) .build(); } } } return client; } private static class LogIntercepter implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); long t1 = System.nanoTime(); Log.i("google.karlo", String.format("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers())); Response response = chain.proceed(request); long t2 = System.nanoTime(); Log.i("google.karlo", String.format("Response message for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers())); return response; } } private static class CacheControlIntercepter implements Interceptor { private static final String TAG = "CacheControlIntercepter"; @Override public Response intercept(Chain chain) throws IOException { Log.i("google.karlo", "CacheControlIntercepter"); Request request = chain.request(); if (!NetWorkUtil.isNetAvailable()) { Log.i("google.karlo", "CacheControlIntercepter: request not network"); request = request.newBuilder() /*没网,强制从内存中读取*/ .cacheControl(CacheControl.FORCE_CACHE) .build(); } Response response = chain.proceed(request); if (NetWorkUtil.isNetAvailable()) { Log.i("google.karlo", "CacheControlIntercepter: response ; isAvailable "); // String cacheControl = request.cacheControl().toString(); // Log.i("Google.Karlo", TAG + "- intercept:" + cacheControl); /*有网络,设置缓存时长*/ return response.newBuilder() .removeHeader("Pragma") // .removeHeader("Cache-Control") .header("Cache-Control", CACHE_AGE) .build(); } else { /*没网络,查询缓存的Cache-Control设置,为if-only-cache时只查询缓存而不会请求服务器,max-stake可以配合设置缓存失效时间 * max-stale 指示客户端可以接受超出超时期间的响应消息。如果指定max-stale消息的值,那么客户端可接受超出超时期指定值之内的响应消息 * */ Log.i("google.karlo", "CacheControlIntercepter: response ; not isAvailable "); return response.newBuilder() .removeHeader("Pragma") // .removeHeader("Cache-Control") .header("Cache-Control", CACHE_STALE) .build(); } } } /** * 根据网络状况获取缓存策略 * @return */ public static String getCacheControl() { return NetWorkUtil.isNetAvailable() ? CACHE_AGE : CACHE_STALE; } private static class RequestIntercepter implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); ConnectivityManager manager = (ConnectivityManager) MyApp.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = manager.getActiveNetworkInfo(); if (activeNetworkInfo == null || !activeNetworkInfo.isAvailable() || !activeNetworkInfo.isConnected()) { Log.i("google.karlo", "RequestIntercepter: request not isAvailable"); request = request.newBuilder() .cacheControl(CacheControl.FORCE_CACHE) .build(); } return chain.proceed(request); } } }