OKHttp的基本使用

1.准备
引入OKHttp
implementation ‘com.squareup.okhttp3:okhttp:4.9.0’
添加权限

<uses-permission android:name="android.permission.INTERNET"/>

以下是Okhttp官方提供的标准demo稍作修改而来

2.get请求

    private void doOKHttpGet() {Runnable runnable = () -> {String response = "";try {response = getRequest("https://raw.github.com/square/okhttp/master/README.md");} catch (IOException e) {Log.d(TAG, e.getMessage());e.printStackTrace();}Log.d(TAG, "doOKHttpGet: " + response);};Thread thread = new Thread(runnable);thread.start();}String getRequest(String url) throws IOException {Request request = new Request.Builder().url(url).build();try (Response response = client.newCall(request).execute()) {return response.body().string();}}

3.post请求

    private void doOKHttpPost() {Runnable runnable = () -> {String json = bowlingJson("Jesse", "Jake111");String response = "";try {response = post("http://www.roundsapp.com/post", json);} catch (IOException e) {Log.d(TAG, e.getMessage());e.printStackTrace();}Log.d(TAG, "doOKHttpPost: " + response);};Thread thread = new Thread(runnable);thread.start();}public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");String post(String url, String json) throws IOException {RequestBody body = RequestBody.create(json, JSON);Request request = new Request.Builder().url(url).post(body).build();try (Response response = client.newCall(request).execute()) {return response.body().string();}}//模拟json数据String bowlingJson(String player1, String player2) {return "{'winCondition':'HIGH_SCORE',"+ "'name':'Bowling',"+ "'round':4,"+ "'lastSaved':1367702411696,"+ "'dateStarted':1367702378785,"+ "'players':["+ "{'name':'" + player1 + "','history':[10,8,6,7,8],'color':-13388315,'total':39},"+ "{'name':'" + player2 + "','history':[6,10,5,10,10],'color':-48060,'total':41}"+ "]}";}

测试结果可以通过log和log中的url查看

对http框架进行封装

本节目的是对OKHttp进行封装,如果不进行封装,我们可能在业务逻辑到处使用到OKHttp,如果我们想切换http引擎,则变成非常繁重的工作

PS:由于内涵段子服务器已经不可访问 因此本文的测试链接改为baidu,因此返回类型不能返回为Json对象,另外 本节的主要关注点应该是框架部分,即是如何让OKHttp可以被其他引擎替换的,代码部分有些不太好懂的部分可以先行跳过
大致类图

代码部分

public interface EngineCallBack {// 调用http接口时最开始回调的方法public void onPreExecute(Context context, Map<String, Object> params);// 错误时的回调public void onError(Exception e);// 成功时的回调// 为什么不返回对象而返回String 除非成功失败返回同一种对象,否则返回对象会出问题,例如成功返回data对象的json数组  失败返回字符串 那么解析的时候会出问题// 返回对象可以在子类中实现public void onSuccess(String result);// 默认的回调 什么都不处理(相当于没有回调)public final EngineCallBack DEFAULT_CALL_BACK = new EngineCallBack() {@Overridepublic void onPreExecute(Context context, Map<String, Object> params) {}@Overridepublic void onError(Exception e) {}@Overridepublic void onSuccess(String result) {}};
}
interface IHttpEngine {// get请求void get(Context context, String url, Map<String, Object> params, EngineCallBack callBack);// post请求void post(Context context, String url, Map<String, Object> params, EngineCallBack callBack);// 优化空间// 1下载文件// 2上传文件// 3 https 添加证书
}
public class OkHttpEngine implements IHttpEngine {private static final String TAG = "OkHttpEngine";private static OkHttpClient mOkHttpClient = new OkHttpClient();@Overridepublic void post(Context context, String url, Map<String, Object> params, EngineCallBack callBack) {// 拼装参数final String jointUrl = HttpUtils.jointParams(url, params);Log.e("TAG", "post 请求Url" + jointUrl);RequestBody requestBody = appendBody(params);// OKHttp官网标准request构造request方法Request request = new Request.Builder().url(url).tag(context).post(requestBody).build();// OKHttp官方标准调用方式mOkHttpClient.newCall(request).enqueue(new Callback() {// 注意,两个回调方法都不是在主线程中 不要在这里直接操作UI@Overridepublic void onFailure(okhttp3.Call call, IOException e) {callBack.onError(e);}@Overridepublic void onResponse(okhttp3.Call call, Response response) throws IOException {String result = response.body().string();Log.e(TAG, "Post返回结果:" + jointUrl);callBack.onSuccess(result);}});}protected RequestBody appendBody(Map<String, Object> params) {MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);addParams(builder, params);return builder.build();}// 添加参数private void addParams(MultipartBody.Builder builder, Map<String, Object> params) {if (params != null && !params.isEmpty()) {for (String key : params.keySet()) {builder.addFormDataPart(key, params.get(key) + "");Object value = params.get(key);if (value instanceof File) {// 处理文件 --> Object FileFile file = (File) value;builder.addFormDataPart(key, file.getName(), RequestBody.create(MediaType.parse(guessMimeType(file.getAbsolutePath())), file));} else if (value instanceof List) {// 代表提交的是 List集合 //为什么说List里面一定是File?try {List<File> listFiles = (List<File>) value;for (int i = 0; i < listFiles.size(); i++) {// 获取文件File file = listFiles.get(i);builder.addFormDataPart(key + i, file.getName(), RequestBody.create(MediaType.parse(guessMimeType(file.getAbsolutePath())), file));}} catch (Exception e) {e.printStackTrace();}} else {builder.addFormDataPart(key, value + "");}}}}private String guessMimeType(String path) {FileNameMap fileNameMap = URLConnection.getFileNameMap();String contentTypeFor = fileNameMap.getContentTypeFor(path);if (contentTypeFor == null) {contentTypeFor = "application/octet-stream";}return contentTypeFor;}@Overridepublic void get(Context context, String url, Map<String, Object> params, EngineCallBack callBack) {url = HttpUtils.jointParams(url, params);Log.e(TAG, "Get请求路径:" + url);Request request = new Request.Builder().url(url).tag(context).build();mOkHttpClient.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {callBack.onError(e);}@Overridepublic void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {if (response.body() == null) {Log.e(TAG, "Get返回结果是null");return;}String resultJson = response.body().string();callBack.onSuccess(resultJson);Log.e("Get返回结果:", resultJson);}});}
}
public class HttpUtils {// 直接带参数 都存放在String中private String mUrl;// 请求方式private int mRequestType = GET_TYPE;private static final int POST_TYPE = 0x0001;private static final int GET_TYPE = 0x0002;// 存放参数private Map<String,Object> mParams;private Context mContext;private HttpUtils(Context context){mContext = context;mParams = new HashMap<>();}// 存放 contextpublic static HttpUtils with(Context context){return new HttpUtils(context);}//传入urlpublic HttpUtils url(String url){this.mUrl = url;return this;}// 传入请求的方式(两种方式)public HttpUtils post(){mRequestType = POST_TYPE;return this;}public HttpUtils get(){mRequestType = GET_TYPE;return this;}// 传入参数(两种方式)public HttpUtils addParam(String key,Object value){mParams.put(key, value);return this;}public HttpUtils addParams(Map<String,Object> params){mParams.putAll(params);return this;}// http请求开始执行public void execute(EngineCallBack callBack){if(callBack == null){callBack = EngineCallBack.DEFAULT_CALL_BACK;}// 预执行部分callBack.onPreExecute(mContext,mParams);// 判断执行方法if(mRequestType == POST_TYPE){post(mUrl,mParams,callBack);}if(mRequestType == GET_TYPE){get(mUrl, mParams, callBack);}}public void execute(){execute(null);}// 默认OkHttpEngineprivate static IHttpEngine mHttpEngine;// 在Application初始化引擎public static void init(IHttpEngine httpEngine) {mHttpEngine = httpEngine;}// 切换其他引擎public HttpUtils exchangeEngine(IHttpEngine httpEngine){mHttpEngine = httpEngine;return this;}private void get(String url, Map<String, Object> params, EngineCallBack callBack) {mHttpEngine.get(mContext, url, params, callBack);}private void post(String url, Map<String, Object> params, EngineCallBack callBack) {mHttpEngine.post(mContext, url, params, callBack);}/*** 将params中的参数拼接到url上*/public static String jointParams(String url, Map<String, Object> params) {if (params == null || params.size() <= 0) {return url;}StringBuilder stringBuilder = new StringBuilder(url);// 如果url中没有? 在末尾加一个?if (!url.contains("?")) {stringBuilder.append("?");} else {// url中已经存在? 如果不是以?结尾 在末尾加上一个&if (!url.endsWith("?")) {stringBuilder.append("&");}}//上述操作之后 该url以?或者&结尾for (Map.Entry<String, Object> entry : params.entrySet()) {//将参数一个个拼接到Url上stringBuilder.append(entry.getKey() + "=" + entry.getValue() + "&");}//删除最后一个&stringBuilder.deleteCharAt(stringBuilder.length() - 1);return stringBuilder.toString();}//貌似是获取object的类型public static Class<?> analysisClazzInfo(Object object) {Type genType = object.getClass().getGenericSuperclass();Type[] params = ((ParameterizedType) genType).getActualTypeArguments();return (Class<?>) params[0];}
}
public abstract class DefaultHttpCallBack<T> implements EngineCallBack {@Overridepublic void onPreExecute(Context context, Map<String, Object> params) {// 固定参数部分 暂时写死
//        params.put("app_name","joke_essay");
//        params.put("version_name","5.7.0");
//        params.put("ac","wifi");
//        params.put("device_id","30036118478");
//        params.put("device_brand","Xiaomi");
//        params.put("update_version_code","5701");
//        params.put("manifest_version_code","570");
//        params.put("longitude","113.000366");
//        params.put("latitude","28.171377");
//        params.put("device_platform","android");onPreExecute();}@Overridepublic void onSuccess(String result) {//        Gson gson = new Gson();
//        // data:{"name","darren"}   data:"请求失败"
//        T objResult = (T) gson.fromJson(result,
//                HttpUtils.analysisClazzInfo(this));
//        onSuccess(objResult);T objResult = (T) result;onSuccess(objResult);}// 以下是三个子类必须实现的方法// 返回可以直接操作的对象public abstract void onSuccess(T result);// 开始执行了public abstract void onPreExecute();@Overridepublic abstract void onError(Exception e);
}

activity中的测试代码

    private void doMyHttpRequest(View view) {HttpUtils.init(new OkHttpEngine());HttpUtils.with(MainActivity.this).exchangeEngine(new OkHttpEngine())
//                .addParam("iid", "6152551759")
//                .addParam("aid", "7")
//                .url("http://is.snssdk.com/2/essay/discovery/v3/").url("https://www.baidu.com/")
//                .post().execute(new DefaultHttpCallBack() {@Overridepublic void onSuccess(Object result) {Log.d(TAG, "onSuccess: " + result);}@Overridepublic void onPreExecute() {Log.d(TAG, "onPreExecute: ");}@Overridepublic void onError(Exception e) {Log.d(TAG, "onError: "+e.getStackTrace());}});}

打印如下类似log应该是成功了

2021-03-11 21:19:11.096 22075-22075/com.example.learneassyjoke D/MyActivity: onPreExecute:
2021-03-11 21:19:11.096 22075-22075/com.example.learneassyjoke E/OkHttpEngine: Get请求路径:https://www.baidu.com/
2021-03-11 21:19:16.923 22075-22157/com.example.learneassyjoke D/MyActivity: onSuccess: <!DOCTYPE html><!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

当然 有兴趣的可以自己搭个Apache服务器 访问自己的本地服务器 返回Json对象而后进行解析

红橙Darren视频笔记 OKHttp基本使用 对http框架进行封装 链式调用相关推荐

  1. 红橙Darren视频笔记 UML图简介

    整体架构复制自红橙原视频的课堂笔记 因为他这一课没有博客,所以没有转载链接,CSDN没有转载地址是无法作为转载类型的文章发表的,暂时标记为原创 参考链接 https://blog.csdn.net/r ...

  2. 红橙Darren视频笔记 代理模式 动态代理和静态代理

    红橙Darren视频笔记 代理模式 动态代理和静态代理(Android API 25) 关于代理模式我之前有过相关的介绍: https://blog.csdn.net/u011109881/artic ...

  3. 红橙Darren视频笔记 类加载机制(API28) 自己写个热修复 查看源码网站

    第一部分 类加载机制 一个Activity是如何被Android虚拟机找到的? 在之前的文章 红橙Darren视频笔记 自定义View总集篇(https://blog.csdn.net/u011109 ...

  4. 红橙Darren视频笔记 利用阿里巴巴AndFix进行热修复

    注意 由于AndFix在2017年左右就停止更新了,在最新版本的apk上遇到很多问题,我最终也没有成功进行热修复.本节主要是学习热修复的原理 在上一篇 红橙Darren视频笔记 自己捕获异常并保存到本 ...

  5. 红橙Darren视频笔记 Behavior的工作原理源码分析

    主要coordinatorlayout的代码来自coordinatorlayout-1.0.0-sources.jar 本文从源码介绍 CoordinatorLayout 的 behavior 怎么工 ...

  6. 红橙Darren视频笔记 仿QQ侧滑效果

    这一篇没有什么新的内容 就是改写 红橙Darren视频笔记 仿酷狗侧滑效果 的侧滑的效果 1.去掉淡入淡出效果 2.加上黑色模板效果 效果: 去掉淡入淡出效果很简单 就是注释掉onScrollChan ...

  7. 红橙Darren视频笔记 ViewGroup事件分发分析 基于API27

    本节目标,通过案例,先看程序运行结果,然后跟踪源码,理解为什么会有这样的输出,继而理解view group的分发机制,感觉和证明题很像呢. 考虑以下程序的运行结果: case1: public cla ...

  8. 红橙Darren视频笔记 view的绘制流程(上) onMeasure测量代码分析 基于API27

    一.准备工作Activity的onCreate和onResume调用过程 从ActivityThread的handleLaunchActivity开始进行代码跟踪 private void handl ...

  9. 红橙Darren视频笔记 自定义TextView 基线的理解 问题引申(viewgroup 不触发onDraw方法)

    1.自定义属性以备使用 新建attrs.xml <?xml version="1.0" encoding="utf-8"?> <resourc ...

最新文章

  1. xtrabackup 使用说明(续)
  2. 查询SDE数据库,GSON报错:declares mutiple JSON fields named data
  3. Java中Scanner的理解大总结
  4. 架构畅想:如果以你所会去进行架构,会到哪一步?
  5. 机器学习非监督学习—k-means及案例分析
  6. f2blog最新注入漏洞
  7. maven eclipse操作
  8. 开源html5游戏-少年行
  9. matlab波导色散,有效折射率法求矩形波导色散曲线(附Matlab程序)
  10. Ajax的回调函数(callback)
  11. asp车衣太阳膜改色膜电子质保卡保修卡实现原理
  12. 在微信支付宝提现时候对输入框输入值的判断
  13. 微流控芯片进样用多通道正负压力控制器的解决方案
  14. MATLAB(九)数值微积分
  15. iOS---学习研究大牛Git高星项目YYCategories(三)
  16. IHERB上待产包准备指南-宝宝篇
  17. matlab 水平投影,matlab图像处理方面的问题。水平投影和垂直投影!
  18. spring form标签的使用
  19. javaweb知识点总结(黑马视频笔记)
  20. unity3d游戏开发之 游戏贴图、模型基本规范(QA)

热门文章

  1. linux用什么剪辑视频教程,Linux 上的开源视频剪辑软件Olive
  2. dubbo源码深度解析_scrapy框架通用爬虫、深度爬虫、分布式爬虫、分布式深度爬虫,源码解析及应用
  3. 栈溢出脚本_漏洞练习之网络编程与堆栈溢出技术
  4. Codeforces | CF1029F 【Multicolored Markers】
  5. 探索Windows命令行系列(7):通过命令编译C#类和Java类
  6. LeetCode Min Stack 最小值栈
  7. 用C#生成随机中文汉字验证码
  8. php批量新增数据类型,Yii框架批量插入数据扩展类的简单实现方法
  9. dev中循环展示图片的样式怎么写_图中的这种样式怎么用HTML写?
  10. 云和恩墨:2020是国产数据库崛起的发轫之年