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

前言:

上一篇我们讲到了基本的Okhttp的封装,只需要我们在代码种调用okHttpUtils.getInstance().GET(url, MyCallBack),一句话完事,而且还是链式的,只需要在MyCallBack中处理返回的Response即可,是不是感觉很爽,不要着急,接下来会让你更爽,请自行准备纸巾,条件允许的话也可以为你的宝贝充上气。没有看过上篇文章的,最好看一下,点击即可跳转: 超简单的okhttp封装工具类(上)
好了,废话不多说,进入正题,本篇主要思想是,通过上篇的封装,联网成功后,返回的是Response对象,我们平时联网需要的结果是一个JavaBean或者一个集合,泛型为JavaBean。那么,接下来就是实现直接返回带泛型的集合,而不是还需要我们处理的Response。

MyCallBack接口的改写

首先,在MyCallBack后面加上泛型,到时候需要实例化这个callback时候,自然的把我们需要转换成的JavaBean以泛型的形式传递过去。
本篇采用Gson进行Response的json转换,所以需要根据泛型获取Type对象。获取方法如下:

//根据T获取Type
static Type getSuperclassTypeParameter(Class<?> subclass)
{
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class)
{
throw new RuntimeException("Missing type parameter.");
}
ParameterizedType parameterized = (ParameterizedType) superclass;
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

我们原来定义的MyCallBack为接口,此时需要改写成抽象类,因为要用到构造方法进行构造Type对象。具体代码如下:

public abstract class MyCallBack<T> {

public  Type mType;

static Type getSuperclassTypeParameter(Class<?> subclass)
{
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class)
{
throw new RuntimeException("Missing type parameter.");
}
ParameterizedType parameterized = (ParameterizedType) superclass;
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
} public MyCallBack() {
mType = getSuperclassTypeParameter(getClass());
} public abstract void onLoadingBefore(Request request);
//第二个参数为传入的泛型,也就是说返回的结果直接就是我们需要的类型
public abstract void onSuccess(Response response, T result); public abstract void onFailure(Request request, Exception e); public abstract void onError(Response 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

OkHttpUtils工具类的改写

我们主要是改写Response返回的地方,也就是联网逻辑这一块,即requestNetWork()方法。具体请看代码实现,注释很清晰。

private void requestNetWork(Request request, MyCallBack<Object> 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()) { String resultStr = response.body().string();
if (callBack.mType == String.class) {
// 如果想要返回字符串 直接返回就行
mHandler.post(() -> callBack.onSuccess(response, resultStr));
} else {
// 需要返回解析好的javaBean集合
try {
// 此处暂时写成object,使用时返回具体的带泛型的集合
Object obj = mGson.fromJson(resultStr, callBack.mType);
mHandler.post(() -> callBack.onSuccess(response, obj));
} catch (Exception e) {
// 解析错误时
mHandler.post(() -> callBack.onError(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

界面联网具体操作

具体使用方法如下:在Fragment的OnCreatView方法中写的逻辑,根据需求自己选择在哪里联网,此处只是测试,不建议在这个方法中处理。会阻塞界面显示。

private String url = "http://222.133.11.150:8402/EnvService/Version/CheckVersion?imei=860806029044186&version=111";

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { OkHttpUtils.getInstance().Get(url, new MyCallBack<ceshiBean>() { @Override
public void onLoadingBefore(Request request) { } @Override
public void onSuccess(Response response, ceshiBean result) {
System.out.println("-----" + result.getStrApkUrl());
} @Override
public void onFailure(Request request, Exception e) { } @Override
public void onError(Response response) { }
}); return inflater.inflate(R.layout.fragment_home,container,false);
}
 
  • 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

ceshiBean的代码

这是我们根据接口写的javaBean对象
public class ceshiBean {

/**
* StrApkUrl : http://222.133.11.150:8402/EnvService/versioninfo/EnvDS_DZ.apk
* StrUpdateDate : 2017.4.18
* StrUpdateFlag : 0
* StrUpdateLog :
1.城市空气模块,新增加乡镇站、边界站、农村站交通站。 * StrVersionCode : 110
* StrVersionName : 1.1.0
*/ private String StrApkUrl;
private String StrUpdateDate;
private String StrUpdateFlag;
private String StrUpdateLog;
private String StrVersionCode;
private String StrVersionName; public String getStrApkUrl() {
return StrApkUrl;
} public void setStrApkUrl(String StrApkUrl) {
this.StrApkUrl = StrApkUrl;
} public String getStrUpdateDate() {
return StrUpdateDate;
} public void setStrUpdateDate(String StrUpdateDate) {
this.StrUpdateDate = StrUpdateDate;
} public String getStrUpdateFlag() {
return StrUpdateFlag;
} public void setStrUpdateFlag(String StrUpdateFlag) {
this.StrUpdateFlag = StrUpdateFlag;
} public String getStrUpdateLog() {
return StrUpdateLog;
} public void setStrUpdateLog(String StrUpdateLog) {
this.StrUpdateLog = StrUpdateLog;
} public String getStrVersionCode() {
return StrVersionCode;
} public void setStrVersionCode(String StrVersionCode) {
this.StrVersionCode = StrVersionCode;
} public String getStrVersionName() {
return StrVersionName;
} public void setStrVersionName(String StrVersionName) {
this.StrVersionName = StrVersionName;
}
}
 
  • 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

总结

到此为止,已经实现了简化逻辑,只需要调用方法时候传入泛型javaBean即可,就能直接获取数据了。

可能有的小伙伴会说,这只是单个javaBean对象的解析,如果我们接口返回的是好对个javaBean的集合,怎么办,so easy,只需要把泛型写成List的形式就好了,直接给你返回一个集合数据集,太爽了。

当然,还有更方便的写法,你可以再次自定义一个具体的CallBack继承MyCallBack,实现里面的方法,在联网开始前显示加载对话框,解析结束隐藏对话框,处理相应的逻辑。那么在前台界面只需要处理你自己的数据就可以了。

声明:本文实现思路是参考IVan的封装思路,只做学习用途。

OkHttpUtils改进后的源码


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 Gson mGson; 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()); mGson = new Gson();
} 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<Object> 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()) { String resultStr = response.body().string();
if (callBack.mType == String.class) {
// 如果想要返回字符串 直接返回就行
mHandler.post(() -> callBack.onSuccess(response, resultStr));
} else {
// 需要返回解析好的javaBean集合
try {
// 此处暂时写成object,使用时返回具体的带泛型的集合
Object obj = mGson.fromJson(resultStr, callBack.mType);
mHandler.post(() -> callBack.onSuccess(response, obj));
} catch (Exception e) {
// 解析错误时
mHandler.post(() -> callBack.onError(response));
} } } else {
mHandler.post(() -> callBack.onError(response));
}
}
}); } }

超简单的okHttpUtils封装(下)的更多相关文章

  1. 超简单的okhttp封装工具类(上)

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

  2. (超简单)VScode配置C/C++环境图文教程(Windows系统下)

    (超简单)VScode配置C/C++环境图文教程(Windows系统下) 本文参考文章 Visual Studio Code (vscode) 配置 C / C++ 环境 下载VScode.下载Min ...

  3. mysql 5.7.29 在centos7.6下超简单的本地yum源安装与配置

    目录 生成yum源元数据 从网易镜像站下载MySQL 5.7 的 bundle包 创建文件 mysql-local.repo 执行yum install命令 生成yum源元数据 createrepo ...

  4. jsp学习---使用jsp和JavaBean实现超简单网页计算器

    一.需求 如题,用jsp实现一个超简单的网页计算器. 二.实现 1.效果图 1)初始界面: 2)随便输入两个数进行相乘: 3)当除数为零时提示报错: 2.代码 Calculator.java pack ...

  5. vuex其实超简单,只需3步

    前言 之前几个项目中,都多多少少碰到一些组件之间需要通信的地方,而因为种种原因,event bus 的成本反而比vuex还高, 所以技术选型上选用了 vuex, 但是不知道为什么,团队里的一些新人一听 ...

  6. 【STM32H7教程】第28章 STM32H7时间关键代码在ITCM执行的超简单方法

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第28章       STM32H7时间关键代码在ITCM执行 ...

  7. 超简单的OpenGL & WebGL & Three.js介绍_1

    专业解释 什么是OpenGL OpenGL(Open Graphics Library即开放图形库或者“开放式图形库”)是用于渲染2D.3D矢量图形的跨语言.跨平台的应用程序编程接口(API). 这个 ...

  8. [C#] 简单的 Helper 封装 -- RegularExpressionHelper

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  9. 把C#程序(含多个Dll)合并成一个Exe的超简单方法

    开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. 但是,很多时候我们本想开发一款只需要一个exe就能完美运行的小工具.那该怎么办呢? 下文介绍一种超 ...

随机推荐

  1. Debian 9 VIM 使用鼠标右键复制

    起因 装了 debian 9 以后,vim没有办法使用鼠标直接选择并复制,后来发现是默认的配置问题.于是需要按照以下方式解决: 解决方法 1. 编辑 vim 的默认配置文件 vim /usr/shar ...

  2. hibernate.properties not found

    在配置hibernate的主键生成策略的时候突然报出如下错误,寻找了很长时间,虽然不是什么严重的错误,但是希望可以警醒自己 问题: 11:26:21,611 INFO Version:37 - HHH ...

  3. 从函数式编程到Ramda函数库(二)

    Ramda 基本的数据结构都是原生 JavaScript 对象,我们常用的集合是 JavaScript 的数组.Ramda 还保留了许多其他原生 JavaScript 特性,例如,函数是具有属性的对象 ...

  4. Java 实现String语句的执行(Jexl)

    https://www.jianshu.com/p/1000719e49fa 1.maven 导入库 <dependency> <groupId>org.apache.comm ...

  5. redis+mysql

    redis和mysql要根据具体业务场景去选型 mysql:数据放在磁盘   redis:数据放在内存 redis适合放一些频繁使用,比较热的数据,因为是放在内存中,读写速度都非常快,一般会应用在下面 ...

  6. Pandas 学习记录(一)

    1.DataFrame 按照列和按照行进行索引数据 按照列索引 df[’column_name’] 按照行索引 df.loc[’row_key’] 或 df.iloc[index] 2.先行后列索引单 ...

  7. 杭电1024----Max Sum Plus Plus

    /* 这题还没有理解透彻.某个dalao也不写注释.只能自己理解了... 先求为i个元素(1<=i<=M)为一个区间的最大和,保证元素个数大于等于i个,递推到M个即可 借鉴原址:http: ...

  8. 在用UEditor往后台传数据写入数据库时,出现错误:从客户端(NewsContent="<p><img src="http://...")中检测到有潜在危险的 Request.。。。

    解决办法: 把传数据的方式换了一下,加上 [ValidateInput(false)]就不报错了. 建议看看这个:http://www.360doc.com/content/10/0521/15/46 ...

  9. 2545 ACM 博客 比较树的路径长短

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2545 题意:比较树的路径长短 思路:利用数组存入父节点的值, 例如: 5 2 1 2 1 3 3 4 3 ...

  10. python反转列表的三种方式

    1.内建函数reversed() li =[1, 2, 3, 4, 5, 6] a = list(reversed(li)) print (a) 注意:reversed()函数返回的是一个迭代器,而不 ...