OkHttp的封装和使用详解
来源:互联网 发布:雅马哈摩托 知乎 编辑:程序博客网 时间:2024/05/19 13:19
其实一直想写这篇文章的,为什么不写呢?因为不想写,不要咬我.我要开始装逼了.接触okhttp是在2015年6月份左右,这已经过去了几年了,但是我对于它的爱犹如滔滔江水,连绵不绝,现在介绍一下,几年前我自己封装的okhttp工具类,拢共就几个类.不会对于造成学习的困扰.开始喽…
因为我已经把它封装为一个工具类,并上传到jcenter仓库,所以大家使用的话,直接gradle应用即可
Github地址
compile 'cn.yuan.yu:library:1.0.2'
使用方法
第一步:初始化我们的工具类
public class MyApplication extends Application { private static Handler mainHandler; private static Context instance; @Override public void onCreate() { super.onCreate(); instance = this; mainHandler = new Handler(); /** * 初始化okhttputils * 第一个参数是是否提交json数据的形式还是表单的形式 * 第二份参数是请求返回的标识code * 第三个参数是请求返回的正确的code值 * 第四个参数是请求返回的提示信息key * 第五个参数是为了同步线程的问题 * 第六个参数是为了弹出提示信息的上下文 */ OkHttpUtilsConfig.getInstance().init(false, "resultcode", "100", "msg", mainHandler,this); }}
第二步,直接调用使用喽,就是这么简单粗暴
JSONObject jsonObject = new JSONObject(); jsonObject.put("username", username); jsonObject.put("password", pwd); L.d("登录", jsonObject.toJSONString()); RequestPacket requestPacket = new RequestPacket(); requestPacket.url = ConstantUrl.getBaseUrl(); requestPacket.addArgument("data", jsonObject.toJSONString()); requestPacket.addArgument("query", "login"); OkHttpUtil.Request(RequestPacket.POST,requestPacket,new ResponseListener<RegistGetVCodeBean>() { @Override public void onSuccess(RegistGetVCodeBean registGetVCodeBean) { //todo somethiing } @Override public void onFailure(String responseresult) { //todo somethiing } });
源码分析
第一步:看下我们封装的参数实体类
package cn.yuan.yu.library.bean;import java.io.Serializable;import java.util.HashMap;import java.util.Map;/** * Created by yukuo on 2015/6/18. * 这是一个请求实体类 */public class RequestPacket implements Serializable { public static final int POST = 1000, GET = 1001;// 定义两个请求类型 public String url;// 请求的网络地址 public Map<String, Object> arguments = new HashMap<>();// 请求参数 public Map<String, String> headers = new HashMap<>();// 请求头 /** * 这是一个添加请求参数的方法 * * @param key * @param value */ public void addArgument(String key, Object value) { arguments.put(key, value); } /** * 这是一个添加头信息参数的方法 * * @param key * @param value */ public void addHeader(String key, String value) { headers.put(key, value); } /** * 这是一个根据键获取参数值得方法 * * @param key * @return */ public Object getArgument(String key) { return arguments.get(key); } /** * 这是一个根据键获取头信息值得方法 * * @param key * @return */ public String getHeader(String key) { return headers.get(key); }}
第二步看下我们封装的配置工具类
package cn.yuan.yu.library;import android.content.Context;import android.os.Handler;/** * Created by yukuoyuan on 2017/3/14. * 这是一个okhttp的配置类 */public class OkHttpUtilsConfig { //返回编码key private String ResultCodeKey = ""; //返回编码正确值 private String ResultCodeValue = ""; //返回错误信息值 private String ResultMsgKey = ""; //是否提交json数据//否的话使用表单提交的形式 private boolean isPostJson = false; //用于同步线程 private Handler mainHandler; //是否展示和日志 private boolean isShowLog; //上下文 private Context context; /** * 设置是否使用提交json的形式 * 不设置的话则使用提交表单的形式提交 * * @param postJson 是否 */ public void setPostJson(boolean postJson) { isPostJson = postJson; } /** * 设置返回的编码的key * * @param resultCodeKey key */ public void setResultCodeKey(String resultCodeKey) { ResultCodeKey = resultCodeKey; } /** * 设置返回正确的正确的value * * @param resultCodeValue */ public void setResultCodeValue(String resultCodeValue) { ResultCodeValue = resultCodeValue; } /** * 设置返回信息的字段key * * @param resultMsgKey key */ public void setResultMsgKey(String resultMsgKey) { ResultMsgKey = resultMsgKey; } /** * 这是一个初始化okhttputils的方法 */ public void init(boolean postJson, String resultCodeKey, String resultCodeValue, String resultMsgKey, Handler mainHandler, Context context) { setPostJson(postJson); setResultCodeKey(resultCodeKey); setResultCodeValue(resultCodeValue); setResultMsgKey(resultMsgKey); setMainHandler(mainHandler); setContext(context); } public boolean isPostJson() { return isPostJson; } public String getResultCodeKey() { return ResultCodeKey; } public String getResultCodeValue() { return ResultCodeValue; } public String getResultMsgKey() { return ResultMsgKey; } public Handler getMainHandler() { return mainHandler; } public void setMainHandler(Handler mainhandler) { this.mainHandler = mainhandler; } public boolean isShowLog() { return isShowLog; } public void setShowLog(boolean showLog) { isShowLog = showLog; } public Context getContext() { return context; } public void setContext(Context context) { this.context = context; } private static OkHttpUtilsConfig sInstance; private OkHttpUtilsConfig() { } public static OkHttpUtilsConfig getInstance() { if (sInstance == null) { synchronized (OkHttpUtilsConfig.class) { if (sInstance == null) { sInstance = new OkHttpUtilsConfig(); } } } return sInstance; }}
第三步看下我们封装的回调接口
Ps:做了解析json的操作
package cn.yuan.yu.library.listener;/** * Created by yukuo on 2016/3/18. * 这是一个服务器响应的监听器 */public abstract class ResponseListener<T> { /** * 这是一个返回正确信息的回调方法 * * @param t */ public abstract void onSuccess(T t); /** * 这是一个返回错误信息的回调方法 * * @param responseresult */ public abstract void onFailure(String responseresult);}
第四步:看下我们重量级别的okhttputils
package cn.yuan.yu.library.utils;import com.google.gson.Gson;import com.google.gson.JsonObject;import com.squareup.okhttp.Callback;import com.squareup.okhttp.FormEncodingBuilder;import com.squareup.okhttp.Interceptor;import com.squareup.okhttp.MediaType;import com.squareup.okhttp.OkHttpClient;import com.squareup.okhttp.Request;import com.squareup.okhttp.RequestBody;import com.squareup.okhttp.Response;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.net.ConnectException;import java.net.SocketTimeoutException;import java.util.Set;import java.util.concurrent.TimeUnit;import cn.yuan.yu.library.OkHttpUtilsConfig;import cn.yuan.yu.library.ProgressResponseBody;import cn.yuan.yu.library.R;import cn.yuan.yu.library.bean.RequestPacket;import cn.yuan.yu.library.listener.DonwloadResponseListener;import cn.yuan.yu.library.listener.ResponseListener;/** * Created by yukuo on 2016/3/18. * 这是一个okhttp请求的工具类 */public class OkHttpUtil { private static final OkHttpClient mOkHttpClient = new OkHttpClient(); //请求类型 public static final MediaType mJSON = MediaType.parse("application/json; charset=utf-8"); //请求编码格式 private static final String CHARSET_NAME = "UTF-8"; static { mOkHttpClient.setConnectTimeout(10, TimeUnit.SECONDS); mOkHttpClient.setReadTimeout(10, TimeUnit.SECONDS); mOkHttpClient.setWriteTimeout(10, TimeUnit.SECONDS); } /** * 这是一个get请求拼接请求路径的方法 * * @param requestPacket 请求参数 * @return */ public static String appendUrl(RequestPacket requestPacket) { return requestPacket.url + "?" + appendArguments(requestPacket); } /** * 这是一个拼接get请求请求参数的方法 * * @param requestPacket 请求参数 * @return */ public static String appendArguments(RequestPacket requestPacket) { String argument = ""; for (String key : requestPacket.arguments.keySet()) { if (requestPacket.getArgument(key) != null) { if (argument.equals("")) { argument = key + "=" + requestPacket.getArgument(key); } else { argument = argument + "&" + key + "=" + requestPacket.getArgument(key); } } } return argument; } /** * 这是一个请求的网络的方法 * * @param method 请求方式 * @param requestPacket 参数实体 * @param listener 回调 */ public static void Request(int method, RequestPacket requestPacket, final ResponseListener listener) { Request request = null; Request.Builder builder = new Request.Builder(); //设置请求类型 builder.header("Content-Type", "application/json"); // 添加头信息 for (String key : requestPacket.headers.keySet()) { if (requestPacket.getHeader(key) != null) { builder.header(key, requestPacket.headers.get(key)); } } //设置请求的url if (method == RequestPacket.POST) { //如果是post请求 if (OkHttpUtilsConfig.getInstance().isPostJson()) { RequestBody body = RequestBody.create(mJSON, new Gson().toJson(requestPacket.arguments)); request = new Request.Builder() .url(requestPacket.url) .post(body) .build(); } else { FormEncodingBuilder builer = new FormEncodingBuilder(); Set<String> keysets = requestPacket.arguments.keySet(); for (String key : keysets) { builer.add(key, requestPacket.arguments.get(key).toString()); } request = new Request.Builder() .url(requestPacket.url) .post(builer.build()) .build(); } } else if (method == RequestPacket.GET) { String url = appendUrl(requestPacket); //如果是get请求 request = builder.url(url).build(); } L.i("请求路径和参数", request.toString() + new Gson().toJson(requestPacket.arguments)); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(final Request request, final IOException e) { sendFaliure("", listener, e); } @Override public void onResponse(final Response response) throws IOException { final String result = response.body().string(); JsonObject re = new Gson().toJsonTree(result).getAsJsonObject(); if (re.get(OkHttpUtilsConfig.getInstance().getResultCodeKey()).equals(OkHttpUtilsConfig.getInstance().getResultCodeValue())) { SendSuccess(result, listener); } else { String responseresult = re.get(OkHttpUtilsConfig.getInstance().getResultMsgKey()).getAsString(); sendFaliure(responseresult, listener, null); } } }); } /** * 发送成功回到 * * @param result 返回的结果 * @param listener 回调监听 */ private static void SendSuccess(final String result, final ResponseListener listener) { OkHttpUtilsConfig.getInstance().getMainHandler().post(new Runnable() { @Override public void run() { /** * 获取要转换的json类型 */ Type genType = listener.getClass().getGenericSuperclass(); Class clzss = (Class) ((ParameterizedType) genType).getActualTypeArguments()[0]; try { L.i("返回的结果", result); listener.onSuccess(new Gson().fromJson(result, clzss)); } catch (Exception e) { e.printStackTrace(); } } }); } /** * 发送失败的消息 * * @param responseresult 返回的错误信息 * @param listener 回调监听 * @param e 异常 */ private static void sendFaliure(final String responseresult, final ResponseListener listener, final IOException e) { OkHttpUtilsConfig.getInstance().getMainHandler().post(new Runnable() { @Override public void run() { listener.onFailure(responseresult); if (e instanceof SocketTimeoutException) { T.showLong(OkHttpUtilsConfig.getInstance().getContext(), R.string.net_error); return; } else if (e instanceof ConnectException) { T.showLong(OkHttpUtilsConfig.getInstance().getContext(), R.string.net_null); return; } } }); } /** * 这是一个下载文件的方法 * * @param donwloadurl 下载路径 * @param filepath 文件路径 * @param filename 文件名字 * @param donwloadResponseListener 回调监听 */ public static void donwloadFile(String donwloadurl, final String filepath, final String filename, final DonwloadResponseListener donwloadResponseListener) { //添加拦截器,自定义ResponseBody,添加下载进度 mOkHttpClient.networkInterceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) { Response originalResponse = null; try { originalResponse = chain.proceed(chain.request()); } catch (IOException e) { e.printStackTrace(); } return originalResponse.newBuilder().body( new ProgressResponseBody(originalResponse.body(), donwloadResponseListener)) .build(); } }); //封装请求 Request request = new Request.Builder() //下载地址 .url(donwloadurl) .build(); //发送异步请求 mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { /** * 失败回调监听 */ OkHttpUtilsConfig.getInstance().getMainHandler().post(new Runnable() { @Override public void run() { donwloadResponseListener.onfailure(); } }); } @Override public void onResponse(Response response) throws IOException { //将返回结果转化为流,并写入文件 int len; byte[] buf = new byte[2048]; InputStream inputStream = response.body().byteStream(); //可以在这里自定义路径 File file1 = new File(filepath + filename); FileOutputStream fileOutputStream = new FileOutputStream(file1); while ((len = inputStream.read(buf)) != -1) { fileOutputStream.write(buf, 0, len); } fileOutputStream.flush(); fileOutputStream.close(); inputStream.close(); } }); }}
第五步:我们封装的下载文件相关类
下载回调
package cn.yuan.yu.library.listener;/** * Created by yukoyuan on 16/7/10. * 这是一个下载文件的回调监听 */public interface DonwloadResponseListener { /** * @param bytesRead 已下载字节数 * @param contentLength 总字节数 * @param done 是否下载完成 * @deprecated 计算方式是 (100 * bytesRead) / contentLength * 日志为 45%... */ void OnSuccess(long bytesRead, long contentLength, boolean done); /** * 下载失败的回调方法 */ void onfailure();}
其他代码和工具类
package cn.yuan.yu.library;import com.squareup.okhttp.MediaType;import com.squareup.okhttp.ResponseBody;import java.io.IOException;import cn.yuan.yu.library.listener.DonwloadResponseListener;import okio.Buffer;import okio.BufferedSource;import okio.ForwardingSource;import okio.Okio;import okio.Source;/** * Created by yukoyuan on 16/7/10. * 这是一个下载文件实体的封装 */public class ProgressResponseBody extends ResponseBody { private final ResponseBody responseBody; private final DonwloadResponseListener progressListener; private BufferedSource bufferedSource; public ProgressResponseBody(ResponseBody responseBody, DonwloadResponseListener progressListener) { this.responseBody = responseBody; this.progressListener = progressListener; } @Override public MediaType contentType() { return responseBody.contentType(); } @Override public long contentLength() throws IOException { return responseBody.contentLength(); } @Override public BufferedSource source() throws IOException { if (bufferedSource == null) { bufferedSource = Okio.buffer(source(responseBody.source())); } return bufferedSource; } private Source source(Source source) { return new ForwardingSource(source) { long totalBytesRead = 0L; @Override public long read(Buffer sink, long byteCount) throws IOException { long bytesRead = super.read(sink, byteCount); totalBytesRead += bytesRead != -1 ? bytesRead : 0; progressListener.OnSuccess(totalBytesRead, responseBody.contentLength(), bytesRead == -1); return bytesRead; } }; }}
日志类和Toast类
package cn.yuan.yu.library.utils;import android.util.Log;import cn.yuan.yu.library.OkHttpUtilsConfig;/** * Created by yukuo on 2015/11/18. * 这是一个log的工具类 */public class L { private static boolean flag = OkHttpUtilsConfig.getInstance().isShowLog(); public static void e(String tag, String text) { if (flag) { Log.e(tag, text); } } public static void d(String tag, String text) { if (flag) { Log.d(tag, text); } } public static void i(String tag, String text) { if (flag) { Log.i(tag, text); } } public static void v(String tag, String text) { if (flag) { Log.v(tag, text); } } public static void w(String tag, String text) { if (flag) { Log.w(tag, text); } } public static void wtf(String tag, String text) { if (flag) { Log.wtf(tag, text); } }}
package cn.yuan.yu.library.utils;import android.content.Context;import android.widget.Toast;/** * Created by yukuo on 2016/1/9. * 这是一个toast的工具类 */public class T { public static boolean isShow = true; /** * 短时间显示Toast类型为CharSequence的数据 * * @param context * @param message */ public static void showShort(Context context, CharSequence message) { if (isShow) Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } /** * 短时间显示Toast类型为int的数据 * * @param context * @param message */ public static void showShort(Context context, int message) { if (isShow) Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } /** * 长时间显示Toast类型为CharSequence的数据 * * @param context * @param message */ public static void showLong(Context context, CharSequence message) { if (isShow) Toast.makeText(context, message, Toast.LENGTH_LONG).show(); } /** * 长时间显示Toast类型为int的数据 * * @param context * @param message */ public static void showLong(Context context, int message) { if (isShow) Toast.makeText(context, message, Toast.LENGTH_LONG).show(); } /** * 自定义显示Toast时间类型为CharSequence的数据 * * @param context * @param message * @param duration */ public static void show(Context context, CharSequence message, int duration) { if (isShow) Toast.makeText(context, message, duration).show(); } /** * 自定义显示Toast时间类型为int的数据 * * @param context * @param message * @param duration */ public static void show(Context context, int message, int duration) { if (isShow) Toast.makeText(context, message, duration).show(); }}
至此我们工具类封装完成了,看一下代码,并没有多少,有没有感觉很简单啊,没那么复杂,有什么问题,欢迎留言给我,也欢迎给我star,谢谢思密达们
2 0
- OkHttp的封装和使用详解
- OkHttp的使用和封装
- OKHttp的基本使用和简单封装
- OkHttp简易封装和使用
- okHttp的简单封装使用
- OkHttp的使用详解
- okhttp使用详解和原理
- okhttp-utils的封装之okhttp的使用
- okhttp的使用以及简单的封装
- Android:网络层的封装(使用OkHttp)
- OkHttp的基本使用以及二次封装
- okhttp的二次封装(基本使用)
- OkHttp简单的封装及使用
- OKHTTP的单例和再封装
- 封装的Http请求(HttpURLConnection和okHttp)
- okHttp的封装和拦截器
- Retrofit和OkHttp简单的二次封装
- okhttp的使用及详解
- Mysql主从复制,读写分离中间件--mycat
- 教你如何在云服务器上体验Docker服务!
- 代码中如何设置TextView为不可见
- Linux网络编程基础API
- this原型理解
- OkHttp的封装和使用详解
- makefile的语法及写法(二)
- 剑指offer_14(调整数组顺序使得奇数位于偶数前面)
- mysql忘记密码(windows)
- 计算单词数--空格不一定一个
- 洛谷 3376_[模板]网络最大流
- 优先队列详解
- poj 2010 Moo University
- uva 11059Maximum Product (暴力)