文章目录

  • OKHTTP3.10的GET请求
  • OKHTTP3.10的POST请求
  • OKHTTP3.10的GET封装请求
    • 工具类的单例:
    • get同步请求
    • get异步请求
    • 明文传参拼接URL
    • post异步请求map传参
    • 将参数添加到请求体
    • post异步请求json传参
    • 以json方式传入请求体
    • 以String方式传入请求体
  • 文件上传:
    • 基于http的文件上传(传入文件名和key)
    • 基于http的文件上传,混合参数和文件请求
  • 文件下载
  • 自定义CallBack回调MyDataCallBack
  • 自定义日志拦截器
  • 自定义网络拦截器
  • 工具类详细代码:
  • 源码下载地址:

我们都知道,Retrofit目前是比较火的网络请求框架,本身就是是OKHttp进行了封装,实际干活的还是OKhttp,所以为了更好的用好Retrofit,很有必要复习一下OKHTTP,并且OKhttp的最新版本3.10.0和之前版本的操作也是不尽相同,所以今天重新对他操作一波,从简单实用到常用使用方式的封装均有涉猎,亲测可以正常使用,本文以豆瓣的电影api做测试数据,详细源码下方会有下载地址,时间紧迫,废话不多说,代码就是最好的注释,欢迎fork!
PS:本文主要围绕以下四个文件做操作:

OKHTTP3.10的GET请求

private void getDouBan1() {//1,创建OKHttpClient对象OkHttpClient okHttpClient = new OkHttpClient();//2,创建一个RequestRequest request = new Request.Builder().url(Constant.URL).build();//3,创建一个call对象Call call = okHttpClient.newCall(request);//4,将请求添加到调度中call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) {if (response.isSuccessful()) {try {res = response.body().string();ThreadPoolUtil.execute(new Runnable() {@Overridepublic void run() {Log.d(TAG, res);}});} catch (IOException e) {e.printStackTrace();}}}});}

OKHTTP3.10的POST请求

private void postDouBan() {//1,创建OKHttpClient对象OkHttpClient okHttpClient = new OkHttpClient();//2,创建一个RequestRequestBody requestBody = new FormBody.Builder().add("username", "ytf").add("password", "123").build();Request request = new Request.Builder().url(Constant.URL).post(requestBody).build();//4,将请求添加到调度中okHttpClient.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {try {res = response.body().string();ThreadPoolUtil.execute(new Runnable() {@Overridepublic void run() {
//                                Looper.prepare();
//                                Toast.makeText(MainActivity.this, res, Toast.LENGTH_SHORT).show();Log.d(TAG, res);EventBus.getDefault().post(res);}});} catch (IOException e) {e.printStackTrace();}}}});}

RequestBody示例:

OKHTTP3.10的GET封装请求

工具类的单例:

/*** 懒汉式加锁单例模式* @return*/public OkHTTPManger() {okHttpClient = new OkHttpClient();}public static OkHTTPManger getInstance() {if (instance == null) {synchronized (OkHTTPManger.class) {if (instance == null) {instance = new OkHTTPManger();}}}return instance;}

get同步请求

 /*** get同步请求不需要传参数* 通过response.body().string()获取返回的字符串** @param url* @return*/public String getSyncBackString(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成StringString responseStr = response.body().string();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为String异常" + e.toString());e.printStackTrace();}return null;}
/*** get同步请求* 通过response.body().bytes()获取返回的二进制字节数组** @param url* @return*/public byte[] getSyncBackByteArray(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成Stringbyte[] responseStr = response.body().bytes();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为byte数组异常" + e.toString());e.printStackTrace();}return null;}
 /*** get同步请求* 通过response.body().byteStream()获取返回的二进制字节流** @param url* @return*/public InputStream getSyncBackByteStream(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成StringInputStream responseStr = response.body().byteStream();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为String异常" + e.toString());e.printStackTrace();}return null;}
/*** get同步请求* 通过response.body().byteStream()获取返回的二进制字节流** @param url* @return*/public Reader getSyncBackCharReader(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成StringReader responseStr = response.body().charStream();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为Reader异常" + e.toString());e.printStackTrace();}return null;}

get异步请求

/*** get异步请求不传参数* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String getAsynBackStringWithoutParms(String url, final MyDataCallBack myDataCallBack) {final Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {
//                 Logger.e("GET异步请求为String失败"+e.toString());myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();try {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("GET异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("GET异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}
/*** get异步请求传参数(可以传null)* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String getAsynBackStringWithParms(String url, Map<String, String> params, final MyDataCallBack myDataCallBack) {if (params == null) {params = new HashMap<>();}// 请求url(baseUrl+参数)String doUrl = urlJoint(url, params);final Request request = new Request.Builder().url(doUrl)
//                .header("Cookie", "自动管理更新需要携带的Cookie").build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {
//                 Logger.e("GET异步请求为String失败"+e.toString());myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();try {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("GET异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("GET异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}

明文传参拼接URL

/*** @param url    实际URL的path* @param params* @return*/private static String urlJoint(String url, Map<String, String> params) {StringBuilder realURL = new StringBuilder(Constant.URL);realURL = realURL.append(url);boolean isFirst = true;if (params == null) {params = new HashMap<>();} else {Set<Map.Entry<String, String>> entrySet = params.entrySet();for (Map.Entry<String, String> entry : entrySet) {if (isFirst && !url.contains("?")) {isFirst = false;realURL.append("?");} else {realURL.append("&");}realURL.append(entry.getKey());realURL.append("=");if (entry.getValue() == null) {realURL.append(" ");} else {realURL.append(entry.getValue());}}}return realURL.toString();}

##OKHTTP3.10的POST封装请求

post异步请求map传参

/*** post异步请求map传参* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String postAsynBackString(String url, Map<String, String> params, final MyDataCallBack myDataCallBack) {RequestBody requestBody;if (params == null) {params = new HashMap<>();}FormBody.Builder builder = new FormBody.Builder();/*** 在这对添加的参数进行遍历*/addMapParmsToFromBody(params, builder);requestBody = builder.build();String realURL = urlJoint(url, null);//结果返回final Request request = new Request.Builder().url(realURL).post(requestBody).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();//此处也可以解析为byte[],Reader,InputStreamtry {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("POST异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}

将参数添加到请求体

 private void addMapParmsToFromBody(Map<String, String> params, FormBody.Builder builder) {for (Map.Entry<String, String> map : params.entrySet()) {String key = map.getKey();String value;/*** 判断值是否是空的*/if (map.getValue() == null) {value = "";} else {value = map.getValue();}/*** 把key和value添加到formbody中*/builder.add(key, value);}}

post异步请求json传参

/*** post异步请求json传参* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String postAsynRequireJson(String url, Map<String, String> params, final MyDataCallBack myDataCallBack) {if (params == null) {params = new HashMap<>();}// 将map转换成json,需要引入Gson包String mapToJson = new Gson().toJson(params);final String realURL = urlJoint(url, null);final Request request = buildJsonPostRequest(realURL, mapToJson);Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();//此处也可以解析为byte[],Reader,InputStreamtry {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("POST异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}

效果图:

以json方式传入请求体

*** Json_POST请求参数** @param url  url* @param json json* @return requestBody*/private Request buildJsonPostRequest(String url, String json) {
//        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);RequestBody requestBody = RequestBody.create(JSON, json);return new Request.Builder().url(url).post(requestBody).build();}

以String方式传入请求体

/*** String_POST请求参数** @param url  url* @param json json* @return requestBody*/private Request buildStringPostRequest(String url, String json) {RequestBody requestBody = RequestBody.create(MEDIA_TYPE_MARKDOWN, json);return new Request.Builder().url(url).post(requestBody).build();}

文件上传:

基于http的文件上传(传入文件名和key)

 /*** 基于http的文件上传(传入文件名和key)* 通过addFormDataPart** @param url            URL的Path部分* @param myDataCallBack 自定义回调接口*                       将file作为请求体传入到服务端.* @param fileKey        文件传入服务器的键"image"* @fileName: "pic.png"*/private void upLoadMultiFileSimple(String url, String fileName, String fileKey, final MyDataCallBack myDataCallBack) {File file = new File(Environment.getExternalStorageDirectory(), fileName);RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart(fileKey, fileName, fileBody).build();final String realURL = urlJoint(url, null);final Request request = new Request.Builder().url(realURL).post(requestBody).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {try {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("POST异步文件上传失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步文件上传异常" + e.toString());e.printStackTrace();}}

基于http的文件上传,混合参数和文件请求

 /*** 基于http的文件上传(传入文件数组和key)混合参数和文件请求* 通过addFormDataPart可以添加多个上传的文件** @param url            URL的Path部分* @param myDataCallBack 自定义回调接口*                       将file作为请求体传入到服务端.* @param files          上传的文件* @param fileKeys       上传的文件key集合*/private void upLoadMultiFile(String url, File[] files, String[] fileKeys, Map<String, String> params, final MyDataCallBack myDataCallBack) {if (params == null) {params = new HashMap<>();}final String realURL = urlJoint(url, null);FormBody.Builder builder = new FormBody.Builder();addMapParmsToFromBody(params, builder);RequestBody requestBody = builder.build();MultipartBody.Builder multipartBody = new MultipartBody.Builder();multipartBody.setType(MultipartBody.ALTERNATIVE).addPart(requestBody);if (files != null) {RequestBody fileBody = null;for (int i = 0; i < files.length; i++) {File file = files[i];String fileName = file.getName();fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file);//TODO 根据文件名设置contentTypemultipartBody.addPart(Headers.of("Content-Disposition","form-data; name=\"" + fileKeys[i] + "\"; filename=\"" + fileName + "\""),fileBody);}}final Request request = new Request.Builder().url(realURL).post(multipartBody.build()).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(call.request(), e);}@Overridepublic void onResponse(Call call, Response response)  {try {myDataCallBack.requestSuccess(response.body().string());} catch (Exception e) {e.printStackTrace();Logger.e("POST异步文件上传失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步文件上传异常" + e.toString());e.printStackTrace();}}
***************************************************************************************private String guessMimeType(String fileName) {FileNameMap fileNameMap = URLConnection.getFileNameMap();String contentTypeFor = fileNameMap.getContentTypeFor(fileName);if (contentTypeFor == null) {contentTypeFor = "application/octet-stream";}return contentTypeFor;}

文件下载

/*** 文件下载* @param url path路径* @param destFileDir 本地存储的文件夹路径* @param myDataCallBack 自定义回调接口*/private void downLoadFileAsyn(final String url, final String destFileDir, final MyDataCallBack myDataCallBack){String realURL=urlJoint(url,null);Request request=new Request.Builder().url(realURL).build();Call call=okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(call.request(),e);}@Overridepublic void onResponse(Call call, Response response) {InputStream is = null;byte[] buf = new byte[2048];int len = 0;FileOutputStream fos = null;is = response.body().byteStream();File file = new File(destFileDir, getFileName(url));try {fos = new FileOutputStream(file);while ((len = is.read(buf)) != -1){fos.write(buf, 0, len);}fos.flush();} catch (IOException e) {Logger.e("文件下载异常:",e.getMessage());e.printStackTrace();}finally {if (is != null) {try {is.close();} catch (IOException e) {Logger.e("文件流关闭异常:",e.getMessage());e.printStackTrace();}}if (fos != null) {try {fos.close();} catch (IOException e) {Logger.e("文件流关闭异常:",e.getMessage());e.printStackTrace();}}}//如果下载文件成功,第一个参数为文件的绝对路径sendSuccessResultCallback(file.getAbsolutePath(), myDataCallBack);myDataCallBack.requestSuccess(response.body().toString());}});}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
private String getFileName(String url) {int separatorIndex = url.lastIndexOf("/");return (separatorIndex < 0) ? url : url.substring(separatorIndex + 1, url.length());}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
private void sendSuccessResultCallback(final String absolutePath, final MyDataCallBack myDataCallBack) {ThreadPoolUtil.execute(new Runnable() {@Overridepublic void run() {if (myDataCallBack!=null){myDataCallBack.requestSuccess(absolutePath);}}});}

自定义CallBack回调MyDataCallBack

package com.app.ytf.httpdemo.okhttp;import com.google.gson.internal.$Gson$Types;import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;import okhttp3.Request;/*** @author ytf* 正常情况下多数返回的是string格式,* 如果要接收返回其他类型的数据可以依照需求放开注释,* 使用参照同步请求做法*/
public abstract class MyDataCallBack<T> {//请求数据的返回类型,包含常见的(Bean,List等)Type mType;public MyDataCallBack() {
//        mType=getSuperclassTypeParameter(getClass());}/*** 通过反射返回想要的类型* @param subclass* @return*/static Type getSuperclassTypeParameter(Class<?> subclass) {Type superclass = subclass.getGenericSuperclass();if (superclass instanceof Class) {throw new RuntimeException("未知返回类型");}ParameterizedType parameterized = (ParameterizedType) superclass;return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);}/*** 在请求之前的方法,一般用于加载进度框ProgressBar展示** @param request*/public  abstract void onBefore(Request request);public abstract void requestSuccess(T result);//    void requestSuccess(Reader result) throws Exception;
//    void requestSuccess(InputStream result) throws Exception;
//    void requestSuccess(byte[] result) throws Exception;public abstract void requestFailure(Request request, IOException e);/*** 在请求之后的方法,一般用于加载框隐藏*/public abstract void onAfter();
}

自定义日志拦截器

package com.app.ytf.httpdemo.okhttp;import com.orhanobut.logger.Logger;import java.io.IOException;
import java.util.Locale;import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;/*** @author ytf* 自定义拦截器* Chain 对象可以拿到当前请求的 Request 对象,然后我们可以对Request做二次处理,* 最后生成我们需要的请求,然后再通过网络发送请求到服务端,这样就完成了一次拦截*/
public class HeaderInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();Logger.d(String.format("Sending request %s on %s%n%s", request.url(),  chain.connection(), request.headers()));long t1 = System.nanoTime();okhttp3.Response response = chain.proceed(chain.request());long t2 = System.nanoTime();Logger.d(String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",response.request().url(), (t2 - t1) / 1e6d, response.headers()));okhttp3.MediaType mediaType = response.body().contentType();String content = response.body().string();Logger.json(content);Response response1=chain.proceed(request);Logger.d("返回response:",response1.toString());return response.newBuilder().header("Authorization", "请求头授权信息拦截").body(okhttp3.ResponseBody.create(mediaType, content)).build();}
}

自定义网络拦截器

package com.app.ytf.httpdemo.okhttp;import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;import com.app.ytf.httpdemo.APP;import java.io.IOException;import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;/*** @author ytf* 设置网络拦截器,实现在线和离线缓存*/
public class CacheInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();if (!isNetworkConnected()) {request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();}Response originalResponse = chain.proceed(request);if (isNetworkConnected()) {//有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置(注掉部分)String cacheControl = request.cacheControl().toString();return originalResponse.newBuilder().header("Cache-Control", cacheControl)//.header("Cache-Control", "max-age=3600").removeHeader("Pragma") // 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效.build();} else {
//1.不需要缓存:Cache-Control: no-cache或Cache-Control: max-age=0
//2.如果想先显示数据,在请求。(类似于微博等):Cache-Control: only-if-cachedint maxAge = 60 * 60;return originalResponse.newBuilder().header("Cache-Control", "public, only-if-cached, max-age=" + maxAge).removeHeader("Pragma").build();}}/*** 判断网络是否可用的方法** @return*/private boolean isNetworkConnected() {ConnectivityManager connectivity = (ConnectivityManager) APP.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);if (null != connectivity) {NetworkInfo info = connectivity.getActiveNetworkInfo();if (null != info && info.isConnected()) {if (info.getState() == NetworkInfo.State.CONNECTED) {return true;}}}return false;}}

工具类详细代码:

package com.app.ytf.httpdemo.okhttp;import android.os.Environment;import com.app.ytf.httpdemo.APP;
import com.app.ytf.httpdemo.util.Constant;
import com.app.ytf.httpdemo.util.ThreadPoolUtil;
import com.google.gson.Gson;
import com.google.gson.internal.$Gson$Types;
import com.orhanobut.logger.Logger;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.ConnectException;
import java.net.FileNameMap;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.sql.ParameterMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;/*** @author ytf*/
public class OkHTTPManger {private static OkHttpClient okHttpClient;private volatile static OkHTTPManger instance;//防止多个线程同时访问//提交json数据private static final MediaType JSON = MediaType.parse("application/json;charset=utf-8");//提交字符串数据private static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown;charset=utf-8");private static String responseStrGETAsyn;private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
// 使用getCacheDir()来作为缓存文件的存放路径(/data/data/包名/cache) ,
// 如果你想看到缓存文件可以临时使用 getExternalCacheDir()(/sdcard/Android/data/包名/cache)。private static File cacheFile;private static Cache cache;public OkHTTPManger() {
//        if (APP.getInstance().getApplicationContext().getCacheDir()!=null){
//            cacheFile = new File(APP.getInstance().getCacheDir(), "Test");
//            cache = new Cache(cacheFile, 1024 * 1024 * 10);
//        }okHttpClient = new OkHttpClient();okHttpClient.newBuilder()
//                .addInterceptor(new HeaderInterceptor())
//                .addNetworkInterceptor(new CacheInterceptor())
//                .cache(cache).connectTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).cookieJar(new CookieJar() {@Overridepublic void saveFromResponse(HttpUrl url, List<Cookie> cookies) {cookieStore.put(url.host(), cookies);}@Overridepublic List<Cookie> loadForRequest(HttpUrl url) {List<Cookie> cookies = cookieStore.get(url.host());return cookies != null ? cookies : new ArrayList<Cookie>();
//自动管理Cookie发送Request都不用管Cookie这个参数也不用去response获取新Cookie什么的了。还能通过cookieStore获取当前保存的Cookie。}});}/*** 懒汉式加锁单例模式* @return*/public static OkHTTPManger getInstance() {if (instance == null) {synchronized (OkHTTPManger.class) {if (instance == null) {instance = new OkHTTPManger();}}}return instance;}/*** get同步请求不需要传参数* 通过response.body().string()获取返回的字符串** @param url* @return*/public String getSyncBackString(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成StringString responseStr = response.body().string();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为String异常" + e.toString());e.printStackTrace();}return null;}/*** get同步请求* 通过response.body().bytes()获取返回的二进制字节数组** @param url* @return*/public byte[] getSyncBackByteArray(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成Stringbyte[] responseStr = response.body().bytes();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为byte数组异常" + e.toString());e.printStackTrace();}return null;}/*** get同步请求* 通过response.body().byteStream()获取返回的二进制字节流** @param url* @return*/public InputStream getSyncBackByteStream(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成StringInputStream responseStr = response.body().byteStream();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为String异常" + e.toString());e.printStackTrace();}return null;}/*** get同步请求* 通过response.body().byteStream()获取返回的二进制字节流** @param url* @return*/public Reader getSyncBackCharReader(String url) {Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();// 将response转化成StringReader responseStr = response.body().charStream();return responseStr;} catch (IOException e) {Logger.e("GET同步请求解析为Reader异常" + e.toString());e.printStackTrace();}return null;}/*** get异步请求不传参数* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String getAsynBackStringWithoutParms(String url, final MyDataCallBack myDataCallBack) {final Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {
//                 Logger.e("GET异步请求为String失败"+e.toString());myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();try {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("GET异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("GET异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}/*** get异步请求传参数(可以传null)* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String getAsynBackStringWithParms(String url, Map<String, String> params, final MyDataCallBack myDataCallBack) {if (params == null) {params = new HashMap<>();}// 请求url(baseUrl+参数)String doUrl = urlJoint(url, params);final Request request = new Request.Builder().url(doUrl)
//                .header("Cookie", "自动管理更新需要携带的Cookie").build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {
//                 Logger.e("GET异步请求为String失败"+e.toString());myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();try {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("GET异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("GET异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}/*** post异步请求map传参* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String postAsynBackString(String url, Map<String, String> params, final MyDataCallBack myDataCallBack) {RequestBody requestBody;if (params == null) {params = new HashMap<>();}FormBody.Builder builder = new FormBody.Builder();/*** 在这对添加的参数进行遍历*/addMapParmsToFromBody(params, builder);requestBody = builder.build();String realURL = urlJoint(url, null);//结果返回final Request request = new Request.Builder().url(realURL).post(requestBody).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();//此处也可以解析为byte[],Reader,InputStreamtry {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("POST异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}private void addMapParmsToFromBody(Map<String, String> params, FormBody.Builder builder) {for (Map.Entry<String, String> map : params.entrySet()) {String key = map.getKey();String value;/*** 判断值是否是空的*/if (map.getValue() == null) {value = "";} else {value = map.getValue();}/*** 把key和value添加到formbody中*/builder.add(key, value);}}/*** post异步请求json传参* 通过response.body().string()获取返回的字符串* 异步返回值不能更新UI,要开启新线程** @param url* @return*/public String postAsynRequireJson(String url, Map<String, String> params, final MyDataCallBack myDataCallBack) {if (params == null) {params = new HashMap<>();}// 将map转换成json,需要引入Gson包String mapToJson = new Gson().toJson(params);final String realURL = urlJoint(url, null);final Request request = buildJsonPostRequest(realURL, mapToJson);Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {responseStrGETAsyn = response.body().string();//此处也可以解析为byte[],Reader,InputStreamtry {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("POST异步请求为String解析异常失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步请求解析为String异常" + e.toString());e.printStackTrace();}return responseStrGETAsyn;}/*** Json_POST请求参数** @param url  url* @param json json* @return requestBody*/private Request buildJsonPostRequest(String url, String json) {
//        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);RequestBody requestBody = RequestBody.create(JSON, json);return new Request.Builder().url(url).post(requestBody).build();}/*** String_POST请求参数** @param url  url* @param json json* @return requestBody*/private Request buildStringPostRequest(String url, String json) {RequestBody requestBody = RequestBody.create(MEDIA_TYPE_MARKDOWN, json);return new Request.Builder().url(url).post(requestBody).build();}/*** @param url    实际URL的path* @param params* @return*/private static String urlJoint(String url, Map<String, String> params) {StringBuilder realURL = new StringBuilder(Constant.URL);realURL = realURL.append(url);boolean isFirst = true;if (params == null) {params = new HashMap<>();} else {Set<Map.Entry<String, String>> entrySet = params.entrySet();for (Map.Entry<String, String> entry : entrySet) {if (isFirst && !url.contains("?")) {isFirst = false;realURL.append("?");} else {realURL.append("&");}realURL.append(entry.getKey());realURL.append("=");if (entry.getValue() == null) {realURL.append(" ");} else {realURL.append(entry.getValue());}}}return realURL.toString();}/*** 基于http的文件上传(传入文件名和key)* 通过addFormDataPart** @param url            URL的Path部分* @param myDataCallBack 自定义回调接口*                       将file作为请求体传入到服务端.* @param fileKey        文件传入服务器的键"image"* @fileName: "pic.png"*/private void upLoadMultiFileSimple(String url, String fileName, String fileKey, final MyDataCallBack myDataCallBack) {File file = new File(Environment.getExternalStorageDirectory(), fileName);RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart(fileKey, fileName, fileBody).build();final String realURL = urlJoint(url, null);final Request request = new Request.Builder().url(realURL).post(requestBody).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(request, e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {try {myDataCallBack.requestSuccess(responseStrGETAsyn);} catch (Exception e) {e.printStackTrace();Logger.e("POST异步文件上传失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步文件上传异常" + e.toString());e.printStackTrace();}}/*** 基于http的文件上传(传入文件数组和key)混合参数和文件请求* 通过addFormDataPart可以添加多个上传的文件** @param url            URL的Path部分* @param myDataCallBack 自定义回调接口*                       将file作为请求体传入到服务端.* @param files          上传的文件* @param fileKeys       上传的文件key集合*/private void upLoadMultiFile(String url, File[] files, String[] fileKeys, Map<String, String> params, final MyDataCallBack myDataCallBack) {if (params == null) {params = new HashMap<>();}final String realURL = urlJoint(url, null);FormBody.Builder builder = new FormBody.Builder();addMapParmsToFromBody(params, builder);RequestBody requestBody = builder.build();MultipartBody.Builder multipartBody = new MultipartBody.Builder();multipartBody.setType(MultipartBody.ALTERNATIVE).addPart(requestBody);if (files != null) {RequestBody fileBody = null;for (int i = 0; i < files.length; i++) {File file = files[i];String fileName = file.getName();fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file);//TODO 根据文件名设置contentTypemultipartBody.addPart(Headers.of("Content-Disposition","form-data; name=\"" + fileKeys[i] + "\"; filename=\"" + fileName + "\""),fileBody);}}final Request request = new Request.Builder().url(realURL).post(multipartBody.build()).build();Call call = okHttpClient.newCall(request);try {myDataCallBack.onBefore(request);// 请求加入调度call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(call.request(), e);}@Overridepublic void onResponse(Call call, Response response)  {try {myDataCallBack.requestSuccess(response.body().string());} catch (Exception e) {e.printStackTrace();Logger.e("POST异步文件上传失败" + e.toString());}}});myDataCallBack.onAfter();} catch (Exception e) {Logger.e("POST异步文件上传异常" + e.toString());e.printStackTrace();}}private String guessMimeType(String fileName) {FileNameMap fileNameMap = URLConnection.getFileNameMap();String contentTypeFor = fileNameMap.getContentTypeFor(fileName);if (contentTypeFor == null) {contentTypeFor = "application/octet-stream";}return contentTypeFor;}/*** 文件下载* @param url path路径* @param destFileDir 本地存储的文件夹路径* @param myDataCallBack 自定义回调接口*/private void downLoadFileAsyn(final String url, final String destFileDir, final MyDataCallBack myDataCallBack){String realURL=urlJoint(url,null);Request request=new Request.Builder().url(realURL).build();Call call=okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {myDataCallBack.requestFailure(call.request(),e);}@Overridepublic void onResponse(Call call, Response response) {InputStream is = null;byte[] buf = new byte[2048];int len = 0;FileOutputStream fos = null;is = response.body().byteStream();File file = new File(destFileDir, getFileName(url));try {fos = new FileOutputStream(file);while ((len = is.read(buf)) != -1){fos.write(buf, 0, len);}fos.flush();} catch (IOException e) {Logger.e("文件下载异常:",e.getMessage());e.printStackTrace();}finally {if (is != null) {try {is.close();} catch (IOException e) {Logger.e("文件流关闭异常:",e.getMessage());e.printStackTrace();}}if (fos != null) {try {fos.close();} catch (IOException e) {Logger.e("文件流关闭异常:",e.getMessage());e.printStackTrace();}}}//如果下载文件成功,第一个参数为文件的绝对路径sendSuccessResultCallback(file.getAbsolutePath(), myDataCallBack);myDataCallBack.requestSuccess(response.body().toString());}});}private String getFileName(String url) {int separatorIndex = url.lastIndexOf("/");return (separatorIndex < 0) ? url : url.substring(separatorIndex + 1, url.length());}private void sendSuccessResultCallback(final String absolutePath, final MyDataCallBack myDataCallBack) {ThreadPoolUtil.execute(new Runnable() {@Overridepublic void run() {if (myDataCallBack!=null){myDataCallBack.requestSuccess(absolutePath);}}});}}

源码下载地址:

点击下载demo

OKHttp3.10.0最新版的极致封装相关推荐

  1. 腾讯电脑管家10.0 官方最新版

    腾讯电脑管家10.0 官方最新版 软件大小:43.89MB 软件语言:简体中文 软件性质:常用软件 软件授权:官方版 更新时间:2014-05-23 应用平台:/Win8/Win7/WinXP 腾讯电 ...

  2. Navicat 9.1、10.0 简体中文最新版,注册码(For Mysql)

    Navicat 9.1.10.0 简体中文最新版,注册码(For Mysql) by 尘缘 on 七月 17th, 2011 // Filed Under → MySQL Navicat属于偶的必备开 ...

  3. 安卓系统的导航仪怎么设置导航启动路径为高德地图_界面功能焕然一新!高德地图10.0新版体验...

    [PConline应用]近日高德地图10.0安卓版与iOS版同时上线,作为一名资深高德迷,我自然第一时间下载并更新了它.没让我失望的是,此次新版不但用上了全新的扁平式UI,各项功能模块也有了大幅进步, ...

  4. 计算机一级笔记百度云盘,自带笔记功能搜索强化!百度网盘10.0新版体验

    [PConline应用]近日,百度网盘手机客户端更新到了10.0版本,新版给用户带来了全新的操作界面还有一个比较实用的新功能,一起来看看吧. 简约新界面 自带夜间模式 新版百度网盘手机客户端采用了全新 ...

  5. kafka中文文档(0.10.0)

    kafka中文文档(0.10.0) 作者:链上研发-老杨叔叔 时间:2016-07-22 版本:Apache Kafka 0.10.0 (2016年5月底发布) .目录 kafka中文文档0100 目 ...

  6. 压感Android Webview,您不能错过的 Safari 10.0 新特性

    Web APIs 支持IndexedDB Safari 10.0 对IndexedDB的HTML5本地存储方式实现完整支持W3C标准.通过该API,开发者可以在Web应用的客户端实现离线存储,或者缓存 ...

  7. JustAuth发布1.10.0版本,集成华为和企业微信登录,更加灵活的state缓存

    JustAuth发布1.10.0版本,集成华为和企业微信登录,更加灵活的state缓存 更新内容 新增 增加AuthCache配置类AuthCacheConfig.java,可以自定义缓存有效期以及是 ...

  8. Android 10.0 系统启动之SystemServer进程-[Android取经之路]

    摘要:上一节讲解了Zygote进程的整个启动流程.Zygote是所有应用的鼻祖.SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来.Zygote fork的第一 ...

  9. Android 10.0系统启动之init进程-[Android取经之路]

    摘要:init进程是linux系统中用户空间的第一个进程,进程号为1.当bootloader启动后,启动kernel,kernel启动完后,在用户空间启动init进程,再通过init进程,来读取ini ...

最新文章

  1. 【Java】Java连接Mysql数据库的demo示例
  2. post和get的区别?
  3. python数据类型介绍_python的数据类型简介
  4. SpringAop @AfterThrowing通知中获取异常信息并且在控制台打印
  5. excel数据库_EXCEL憋出大招,逆袭大数据的黑马出现了
  6. 2021年中国一次性弹性泵市场趋势报告、技术动态创新及2027年市场预测
  7. leetcode 打印_leetcode多线程之按序打印
  8. ar9285无线网卡驱动 linux,为Atheros AR9285 wireless network adapter装ubuntu 12.04 LTS linux驱动...
  9. VMware Cloud Director Availability 4.3 下载 | 灾难恢复和迁移 | DRaaS
  10. ROS | 机器人操作系统简介
  11. windows程序介绍
  12. 国二c语言南开版的机试100题,[互联网]免费ncre全国计算机等级考试二级c语言上机---南开100题答案...
  13. word表格转为html5,怎么把网页版的表格转至Word
  14. 关于程序员的调查报告
  15. 楼兰宝盒显示网络服务器无响应,捷达vs5-圈里有谁跟我一样,安装了楼兰宝盒后,用手机启动车子出现无钥匙解锁失灵时候使坏,和前部辅助系统出现故障问题,不用手机启动就没事...
  16. 话说js中的异步编程。
  17. 魅族l681q详细开启Usb调试模式的步骤
  18. python操作ppt
  19. matlab中画网格,matlab怎么画网格
  20. 【嵌入式Linux驱动开发】二十一、Linux内核自带的KEY驱动探索

热门文章

  1. 3dsmax-script脚本
  2. C语言中的`\0`什么意思?
  3. 旅游卡景区购票小程序开发定制
  4. 如何使用腾讯云web应用防火墙结合API网管提供安全防护?
  5. 操作系统练习题(三四五章)
  6. PCM1770测试程序
  7. 面向对象——类的定义
  8. el-select样式两种修改方式index.html或popper-append-to-body加popper-class
  9. 测试TCP,UDP,SSL上行速率C代码(client + tcpserver + ssl )
  10. Keil使用中文兼容设置方法【详细图示】【附字体库】