版权声明:转载请注明出处:http://blog.csdn.net/piaomiao8179 https://blog.csdn.net/piaomiao8179/article/details/70811973

前言:

提及访问网络,很自然的会用到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封装工具类(上)的更多相关文章

  1. 超简单的okHttpUtils封装(下)

      版权声明:转载请注明出处:http://blog.csdn.net/piaomiao8179 https://blog.csdn.net/piaomiao8179/article/details/ ...

  2. Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

    csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...

  3. Android OkHttp网络连接封装工具类

    package com.lidong.demo.utils; import android.os.Handler; import android.os.Looper; import com.googl ...

  4. 实现一个简单的http请求工具类

    OC自带的http请求用起来不直观,asihttprequest库又太大了,依赖也多,下面实现一个简单的http请求工具类 四个文件源码大致如下,还有优化空间 MYHttpRequest.h(类定义, ...

  5. JAVA之旅(五)——this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块

    JAVA之旅(五)--this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块 周末收获颇多,继续学习 一.this关键字 用于区分局部变量和成员变量同名的情况 ...

  6. MySQL JDBC常用知识,封装工具类,时区问题配置,SQL注入问题

    JDBC JDBC介绍 Sun公司为了简化开发人员的(对数据库的统一)操作,提供了(Java操作数据库的)规范,俗称JDBC,这些规范的由具体由具体的厂商去做 对于开发人员来说,我们只需要掌握JDBC ...

  7. 泛型(二)封装工具类CommonUtils-把一个Map转换成指定类型的javabean对象

    1.commons-beanutils的使用 commons-beanutils-1.9.3.jar 依赖 commons-logging-1.2.jar 代码1: String className ...

  8. FTP上传-封装工具类

    import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...

  9. java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能

    这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...

随机推荐

  1. BUG总是存在的

    遇到了一个Bug 前段时间,添加功能的时候,在其他页面的Html中(django)的python调用{{}}中不小心按多了一个空格. 这导致这个值在读取的时候,读取多了一个空格:split的时候,多分 ...

  2. 003.Ansible基础使用

    一 Ansible命令用法 Ansible命令行执行方式有:Ad-Hoc.Ansible-playbook两种,Web方式其官方提供付费产品Tower.Ad-Hoc主要用于临时命令的执行,Ansibl ...

  3. java接口签名(Signature)实现方案

    预祝大家国庆节快乐,赶快迎接美丽而快乐的假期吧!!! 一.前言 在为第三方系统提供接口的时候,肯定要考虑接口数据的安全问题,比如数据是否被篡改,数据是否已经过时,数据是否可以重复提交等问题.其中我认为 ...

  4. Linux内核中Makefile、Kconfig和.config的关系(转)

    我们在编译Linux内核时,往往在Linux内核的顶层目录会执行一些命令,这里我以RK3288举例,比如:make firefly-rk3288-linux_defconfig.make menuco ...

  5. TensorFlow下利用MNIST训练模型并识别自己手写的数字

    最近一直在学习李宏毅老师的机器学习视频教程,学到和神经网络那一块知识的时候,我觉得单纯的学习理论知识过于枯燥,就想着自己动手实现一些简单的Demo,毕竟实践是检验真理的唯一标准!!!但是网上很多的与t ...

  6. Java(Android)线程池zz

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

  7. git提交待审核代码,报错没有change-id的解决方法

    git提交是报错没有change-id的解决方法: 1.先仔细查看报错内容,查出是哪天提交记录缺少change-id 2.如果是最近的一条缺少,则直接执行git commit --amend &quo ...

  8. MySQL连接缓慢,打开缓慢原因

    问题状况:最近由于服务器变换了网段,导致IP地址变换,变化后使用MySQL客户端连接MySQL服务器和在客户端中打开表的速度非常慢(无论表的大小),甚至连接超时,但是直接登录到服务器在本地连接MySQ ...

  9. CodeForce VKcup A

    题目描述:例如A-B,B-C是好朋友,那么A-C一定是好朋友,给一些点,和一些描述,观察是否成立 题目链接:点我 一个互相认识的团体,一定是每个点都和其他点相连的,那么边数为n(n-1)/2,把得到的 ...

  10. MySql中drop、truncate、delete的区别

    1.drop:能对table和view 用法:  drop table [is exists] 表1,表2,表3....: ①drop是DDL中删除表的操作,会删除表结构和所有数据,并释放空间. ②并 ...