package com.novelbook.android.utils; import android.content.Context; import android.util.Log; import com.novelbook.android.BuildConfig; import com.novelbook.android.MyApp; import java.io.File; import java.io.IOException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.TimeUnit; import io.reactivex.annotations.NonNull; import okhttp3.Cache; import okhttp3.CacheControl; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitFactory { private static final Object Object = new Object(); /** * 缓存机制 * 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹,保持缓存数据。 * 这样我们就可以在请求的时候,如果判断到没有网络,自动读取缓存的数据。 * 同样这也可以实现,在我们没有网络的情况下,重新打开App可以浏览的之前显示过的内容。 * 也就是:判断网络,有网络,则从网络获取,并保存到缓存中,无网络,则从缓存中获取。 * https://werb.github.io/2016/07/29/%E4%BD%BF%E7%94%A8Retrofit2+OkHttp3%E5%AE%9E%E7%8E%B0%E7%BC%93%E5%AD%98%E5%A4%84%E7%90%86/ */ //这里是设置拦截器,供下面的函数调用,辅助作用。 private static final Interceptor cacheControlInterceptor = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (!NetWorkUtil.isNetworkConnected(MyApp.applicationContext)) { request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); } Response originalResponse = chain.proceed(request); if (NetWorkUtil.isNetworkConnected(MyApp.applicationContext)) { // 有网络时 设置缓存为默认值 String cacheControl = request.cacheControl().toString(); return originalResponse.newBuilder() .header("Cache-Control", cacheControl) .removeHeader("Pragma") // 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效 .build(); } else { // 无网络时 设置超时为1周 int maxStale = 60 * 60 * 24 * 7; return originalResponse.newBuilder() .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) .removeHeader("Pragma") .build(); } } }; private volatile static Retrofit retrofit; private static String baseUrl ="https://api.douban.com/v2/movie/"; //这个人函数供外部调用,当请求数据时来调用 @NonNull public static Retrofit getRetrofit() { synchronized (Object) { if (retrofit == null) { // 指定缓存路径,缓存大小 50Mb Cache cache = new Cache(new File(MyApp.applicationContext.getCacheDir(), "HttpCache"),1024 * 1024 * 50); // Cookie 持久化 // ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(MyApp.applicationContext)); OkHttpClient.Builder builder = new OkHttpClient.Builder() // .cookieJar(cookieJar) .cache(cache) .addInterceptor(cacheControlInterceptor) .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS) .retryOnConnectionFailure(true); // Log 拦截器 if (BuildConfig.DEBUG) { builder = initInterceptor(builder); } retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .client(builder.build()) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } return retrofit; } } public static OkHttpClient.Builder initInterceptor(OkHttpClient.Builder builder){ HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { try { String text = URLDecoder.decode(message, "utf-8"); Log.e("OKHttp-----", text); } catch ( Exception e) { e.printStackTrace(); Log.e("OKHttp-----", message); } } }); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); builder.addInterceptor(interceptor); // 添加公共参数拦截器 /* BasicParamsInterceptor basicParamsInterceptor = new BasicParamsInterceptor.Builder() .addHeaderParam("userName","")//添加公共参数 .addHeaderParam("device","") .build(); builder.addInterceptor(basicParamsInterceptor);*/ /* // 添加公共参数拦截器 HttpCommonInterceptor commonInterceptor = new HttpCommonInterceptor.Builder() .addHeaderParams("paltform","android") .addHeaderParams("userToken","1234343434dfdfd3434") .addHeaderParams("userId","123445") .build(); builder.addInterceptor(commonInterceptor);*/ return builder; } } /* public class HttpCommonInterceptor implements Interceptor{ private Map mHeaderParamsMap = new HashMap<>(); Map queryParamsMap = new HashMap<>(); Map paramsMap = new HashMap<>(); Map headerParamsMap = new HashMap<>(); List headerLinesList = new ArrayList<>(); public HttpCommonInterceptor() { } @Override public Response intercept(Chain chain) throws IOException { Log.d("HttpCommonInterceptor","add common params"); Request oldRequest = chain.request(); // Request request = chain.request(); Headers.Builder headerBuilder = oldRequest.headers().newBuilder(); Request.Builder requestBuilder = oldRequest.newBuilder(); // 添加新的参数,添加到url 中 */ /* HttpUrl.Builder authorizedUrlBuilder = oldRequest.url() .newBuilder() .scheme(oldRequest.url().scheme()) .host(oldRequest.url().host());*//* if (headerParamsMap.size() > 0) { Iterator iterator = headerParamsMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); headerBuilder.add((String) entry.getKey(), (String) entry.getValue()); } } if (headerLinesList.size() > 0) { for (String line: headerLinesList) { headerBuilder.add(line); } requestBuilder.headers(headerBuilder.build()); } // 新的请求 //Request.Builder requestBuilder = oldRequest.newBuilder(); requestBuilder.method(oldRequest.method(), oldRequest.body()); //添加公共参数,添加到header中 if(mHeaderParamsMap.size() > 0){ for(Map.Entry params:mHeaderParamsMap.entrySet()){ requestBuilder.header(params.getKey(),params.getValue()); } } // process post body inject if (paramsMap.size() > 0) { if (canInjectIntoBody(oldRequest)) { FormBody.Builder formBodyBuilder = new FormBody.Builder(); for(Map.Entry entry : paramsMap.entrySet()) { formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue()); } RequestBody formBody = formBodyBuilder.build(); String postBodyString = bodyToString(oldRequest.body()); postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody); requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString)); } } Request newRequest = requestBuilder.build(); return chain.proceed(newRequest); }*/