超简单的okhttp封装工具类(上)
前言:
提及访问网络,很自然的会用到okHttp,虽然okhttp已经封装的比较完善,
调用也比较方便,但对于向我这样比较懒的人,okhttp的调用还是略显复杂,
每次都要写同样重复的代码,简直不能忍受,那就封装以下一句话调用完毕,岂不快哉。。。
废话不多说,请抓稳扶好,老司机,走起。。。
- 1
- 2
- 3
- 4
重要的事情提一提:看不懂的文章最后有完整代码,看看完整版应该就没问题了。
okHttp使用流程
没有什么是一张图说不清的,走起
- 1
高逼格的封装开始
网络访问框架一般都需要单例模式(singleton),首先我们也进行单利模式。
1 首先私有化构造器,让别人不能new出其它实例。
2 声明该类的一个静态成员变量实例,本篇为instance
3 声明一个公有的方法getInstance提供给调用者本类实例。
/**
* 网络访问要求singleton
*/
private static OkHttpUtils instance;
// 必须要用的okhttpclient实例,在构造器中实例化保证单一实例
private OkHttpClient mOkHttpClient;
private OkHttpUtils() {
/**
* okHttp3中超时方法移植到Builder中
*/
mOkHttpClient = (new OkHttpClient()).newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
public static OkHttpUtils getInstance() {
if (instance == null) {
synchronized (OkHttpUtils.class) {
if (instance == null) {
instance = new OkHttpUtils();
}
}
}
return instance;
}
上面代码在构造器中实例化出了okHttpClient的实例,既然我们这个帮助类是单例的,那么构造器中的okHttpClient也只会走一次,必定也是单实例的。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
提供GET和POST两种访问方式的方法
既然是工具类,肯定要更加简单,此处我们需要提供针对GET和POST两种方式的访问方法。
- 1
1.工具类为GET访问方式提供的方法
/**
* 对外提供的Get方法访问
* @param url
* @param callBack
*/
public void Get(String url, MyCallBack callBack) {
/**
* 通过url和GET方式构建Request
*/
Request request = bulidRequestForGet(url);
/**
* 请求网络的逻辑
*/
requestNetWork(request, callBack);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
2.工具类为POST访问方式提供的方法(表单数据)
/**
* 对外提供的Post方法访问
* @param url
* @param parms: 提交内容为表单数据
* @param callBack
*/
public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) {
/**
* 通过url和POST方式构建Request
*/
Request request = bulidRequestForPostByForm(url, parms);
/**
* 请求网络的逻辑
*/
requestNetWork(request, callBack);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
3.工具类为POST访问提供方法(JSON数据)
/**
* 对外提供的Post方法访问
* @param url
* @param json: 提交内容为json数据
* @param callBack
*/
public void PostWithJson(String url, String json, MyCallBack callBack) {
/**
* 通过url和POST方式构建Request
*/
Request request = bulidRequestForPostByJson(url, json);
/**
* 请求网络的逻辑
*/
requestNetWork(request, callBack);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
从这两个方法,我们能看到我们需要构建GET和POST访问方式对应的Request对象和我们自定义的MycallBack接口,下面先来看一下构建Request对象。
构建Request对象
为了大家更好的理解封装流程,首先请大家回顾一下okhttp的使用流程:
mOkHttpClient.newCall(request).enqueue(new Callback() {})
- 1
- 2
1.首先我们来看构建GET需要的Request对象,这个也是最简单的。
/**
* GET方式构建Request
* @param url
* @return
*/
private Request bulidRequestForGet(String url) {
return new Request.Builder()
.url(url)
.get()
.build();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2.构建提交表单数据的Request对象
/**
* POST方式构建Request {Form}
* @param url
* @param parms
* @return
*/
private Request bulidRequestForPostByForm(String url, Map<String, String> parms) {
FormBody.Builder builder = new FormBody.Builder();
if (parms != null) {
for (Map.Entry<String, String> entry :
parms.entrySet()) {
builder.add(entry.getKey(), entry.getValue());
}
}
FormBody body = builder.build();
return new Request.Builder()
.url(url)
.post(body)
.build();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
3.构建提交json数据的Request对象
/**
* POST方式构建Request {json}
* @param url
* @param json
* @return
*/
private Request bulidRequestForPostByJson(String url, String json) {
RequestBody body = RequestBody.create(JSON, json);
return new Request.Builder()
.url(url)
.post(body)
.build();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
开始处理联网逻辑
上述代码及分析基本上把简单封装的东西讲完了,有了okhttpclient和request对象我们需要处理联网逻辑了,也就是上述的 requestNetWork方法。
private void requestNetWork(Request request, MyCallBack callBack) {
/**
* 处理连网逻辑,此处只处理异步操作enqueue
*/
callBack.onLoadingBefore(request);
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callBack.onFailure(request, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
callBack.onSuccess(response);
} else {
callBack.onError(response);
}
}
});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
MyCallBack对象分析
看到此处,估计有人会一脸懵逼,这个MyCallBack是个什么鬼。
其实这是我定义的一个接口,那么为什么要定义她呢。因为我们在使用我们的工具类的时候,访问网络成功后肯定会有数据返回,我们怎么处理呢,okhttp内部通过一个callBack把数据回调回来,那么我们自己封装的工具类不妨仿照他的做法 定义一个接口回调Response的内容。贴一下接口的内容
interface MyCallBack {
void onLoadingBefore(Request request);
void onSuccess(Response response);
void onFailure(Request request, Exception e);
void onError(Response response);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
}
封装进阶
看到此处,觉得封装已经完结了,不不不,还有一个重要的问题,不处理的话会导致崩溃的,这个问题就是,我们定义接口回调的地方是在子线程,而我们的Response很明显需要拿回到主线程进行UI的更新,所以访问网络的方法requestNetWork需要通过Handler把子线程的Resonse发送到主线程,请看详细实现。
private void requestNetWork(Request request, MyCallBack callBack) {
/**
* 处理连网逻辑,此处只处理异步操作enqueue
*/
callBack.onLoadingBefore(request);
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
mHandler.post(() -> callBack.onFailure(request, e));
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
mHandler.post(() -> callBack.onSuccess(response));
} else {
mHandler.post(() -> callBack.onError(response));
}
}
});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
结束语
此工具类还没有完善,下篇文章继续完善,待完善内容:返回Resonpse直接解析成javaBean返回。
- 1
完整代码
public class OkHttpUtils {
/**
* 网络访问要求singleton
*/
private static OkHttpUtils instance;
// 必须要用的okhttpclient实例,在构造器中实例化保证单一实例
private OkHttpClient mOkHttpClient;
public static final MediaType JSON = MediaType.
parse("application/json; charset=utf-8");
private Handler mHandler;
private OkHttpUtils() {
/**
* okHttp3中超时方法移植到Builder中
*/
mOkHttpClient = (new OkHttpClient()).newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
mHandler = new Handler(Looper.getMainLooper());
}
public static OkHttpUtils getInstance() {
if (instance == null) {
synchronized (OkHttpUtils.class) {
if (instance == null) {
instance = new OkHttpUtils();
}
}
}
return instance;
}
/**
* 对外提供的Get方法访问
* @param url
* @param callBack
*/
public void Get(String url, MyCallBack callBack) {
/**
* 通过url和GET方式构建Request
*/
Request request = bulidRequestForGet(url);
/**
* 请求网络的逻辑
*/
requestNetWork(request, callBack);
}
/**
* 对外提供的Post方法访问
* @param url
* @param parms: 提交内容为表单数据
* @param callBack
*/
public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) {
/**
* 通过url和POST方式构建Request
*/
Request request = bulidRequestForPostByForm(url, parms);
/**
* 请求网络的逻辑
*/
requestNetWork(request, callBack);
}
/**
* 对外提供的Post方法访问
* @param url
* @param json: 提交内容为json数据
* @param callBack
*/
public void PostWithJson(String url, String json, MyCallBack callBack) {
/**
* 通过url和POST方式构建Request
*/
Request request = bulidRequestForPostByJson(url, json);
/**
* 请求网络的逻辑
*/
requestNetWork(request, callBack);
}
/**
* POST方式构建Request {json}
* @param url
* @param json
* @return
*/
private Request bulidRequestForPostByJson(String url, String json) {
RequestBody body = RequestBody.create(JSON, json);
return new Request.Builder()
.url(url)
.post(body)
.build();
}
/**
* POST方式构建Request {Form}
* @param url
* @param parms
* @return
*/
private Request bulidRequestForPostByForm(String url, Map<String, String> parms) {
FormBody.Builder builder = new FormBody.Builder();
if (parms != null) {
for (Map.Entry<String, String> entry :
parms.entrySet()) {
builder.add(entry.getKey(), entry.getValue());
}
}
FormBody body = builder.build();
return new Request.Builder()
.url(url)
.post(body)
.build();
}
/**
* GET方式构建Request
* @param url
* @return
*/
private Request bulidRequestForGet(String url) {
return new Request.Builder()
.url(url)
.get()
.build();
}
private void requestNetWork(Request request, MyCallBack callBack) {
/**
* 处理连网逻辑,此处只处理异步操作enqueue
*/
callBack.onLoadingBefore(request);
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
mHandler.post(() -> callBack.onFailure(request, e));
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
mHandler.post(() -> callBack.onSuccess(response));
} else {
mHandler.post(() -> callBack.onError(response));
}
}
});
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
定义的接口的完整代码
interface MyCallBack {
void onLoadingBefore(Request request);
void onSuccess(Response response);
void onFailure(Request request, Exception e);
void onError(Response response);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
超简单的okhttp封装工具类(上)的更多相关文章
- 超简单的okHttpUtils封装(下)
版权声明:转载请注明出处:http://blog.csdn.net/piaomiao8179 https://blog.csdn.net/piaomiao8179/article/details/ ...
- Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)
csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...
- Android OkHttp网络连接封装工具类
package com.lidong.demo.utils; import android.os.Handler; import android.os.Looper; import com.googl ...
- 实现一个简单的http请求工具类
OC自带的http请求用起来不直观,asihttprequest库又太大了,依赖也多,下面实现一个简单的http请求工具类 四个文件源码大致如下,还有优化空间 MYHttpRequest.h(类定义, ...
- JAVA之旅(五)——this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块
JAVA之旅(五)--this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块 周末收获颇多,继续学习 一.this关键字 用于区分局部变量和成员变量同名的情况 ...
- MySQL JDBC常用知识,封装工具类,时区问题配置,SQL注入问题
JDBC JDBC介绍 Sun公司为了简化开发人员的(对数据库的统一)操作,提供了(Java操作数据库的)规范,俗称JDBC,这些规范的由具体由具体的厂商去做 对于开发人员来说,我们只需要掌握JDBC ...
- 泛型(二)封装工具类CommonUtils-把一个Map转换成指定类型的javabean对象
1.commons-beanutils的使用 commons-beanutils-1.9.3.jar 依赖 commons-logging-1.2.jar 代码1: String className ...
- FTP上传-封装工具类
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...
- java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能
这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...
随机推荐
- BUG总是存在的
遇到了一个Bug 前段时间,添加功能的时候,在其他页面的Html中(django)的python调用{{}}中不小心按多了一个空格. 这导致这个值在读取的时候,读取多了一个空格:split的时候,多分 ...
- 003.Ansible基础使用
一 Ansible命令用法 Ansible命令行执行方式有:Ad-Hoc.Ansible-playbook两种,Web方式其官方提供付费产品Tower.Ad-Hoc主要用于临时命令的执行,Ansibl ...
- java接口签名(Signature)实现方案
预祝大家国庆节快乐,赶快迎接美丽而快乐的假期吧!!! 一.前言 在为第三方系统提供接口的时候,肯定要考虑接口数据的安全问题,比如数据是否被篡改,数据是否已经过时,数据是否可以重复提交等问题.其中我认为 ...
- Linux内核中Makefile、Kconfig和.config的关系(转)
我们在编译Linux内核时,往往在Linux内核的顶层目录会执行一些命令,这里我以RK3288举例,比如:make firefly-rk3288-linux_defconfig.make menuco ...
- TensorFlow下利用MNIST训练模型并识别自己手写的数字
最近一直在学习李宏毅老师的机器学习视频教程,学到和神经网络那一块知识的时候,我觉得单纯的学习理论知识过于枯燥,就想着自己动手实现一些简单的Demo,毕竟实践是检验真理的唯一标准!!!但是网上很多的与t ...
- Java(Android)线程池zz
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
- git提交待审核代码,报错没有change-id的解决方法
git提交是报错没有change-id的解决方法: 1.先仔细查看报错内容,查出是哪天提交记录缺少change-id 2.如果是最近的一条缺少,则直接执行git commit --amend &quo ...
- MySQL连接缓慢,打开缓慢原因
问题状况:最近由于服务器变换了网段,导致IP地址变换,变化后使用MySQL客户端连接MySQL服务器和在客户端中打开表的速度非常慢(无论表的大小),甚至连接超时,但是直接登录到服务器在本地连接MySQ ...
- CodeForce VKcup A
题目描述:例如A-B,B-C是好朋友,那么A-C一定是好朋友,给一些点,和一些描述,观察是否成立 题目链接:点我 一个互相认识的团体,一定是每个点都和其他点相连的,那么边数为n(n-1)/2,把得到的 ...
- MySql中drop、truncate、delete的区别
1.drop:能对table和view 用法: drop table [is exists] 表1,表2,表3....: ①drop是DDL中删除表的操作,会删除表结构和所有数据,并释放空间. ②并 ...