android使用gson和泛型解析服务器回调的封装
2017-06-09 11:49
363 查看
android使用gson和泛型解析服务器回调的封装
android使用gson和泛型解析服务器回调的封装概述
建立通用的回调Model
封装服务器回调
1 回调的抽象基类
2 针对刚才服务器对象封装的抽象子类
使用封装的回调
概述
前面我们介绍了如何使用Gson解析和创建json,这里我们继续介绍如何使用泛型来封装服务器回调。本文主要的技术点有
使用类的泛型和方法的泛型
结合gson封装服务器json回调
1 建立通用的回调Model
以这个服务器回调为例。{ "server_time": 1497611816029, "data": { "name": "jady", "age": 12 }, "success": true }
这个json里面
server_time和
success的类型是固定不变的,但是data的类型却会经常改变,比如这里传回来的是
User,另一个接口传回来的可能就是
Student了。
首先建立对应的类:
public class ServerCallbackModel<T> { private long server_time; private T data; private boolean success; private String err_code; private String message; public long getServer_time() { return server_time; } public void setServer_time(long server_time) { this.server_time = server_time; } public T getData() { return data; } public void setData(T data) { this.data = data; } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public String getErr_code() { return err_code; } public void setErr_code(String err_code) { this.err_code = err_code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
2 封装服务器回调
这里我们写的服务器回调是基于已经拿到服务器回调的json字符串。2.1 回调的抽象基类:
public abstract class HttpCallback<T> { public static final String TAG = "HttpCallback"; protected Type genericityType; public HttpCallback() { Type genericSuperclass = getClass().getGenericSuperclass(); if (genericSuperclass instanceof ParameterizedType) { this.genericityType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0]; } else { this.genericityType = Object.class; } } public abstract void onResolve(T t); public abstract void onFailed(String err_code, String message); public Type getGenericityType() { return genericityType; } }
这里定义了一个构造方法,两个抽象方法,我们先看构造方法,
Type genericSuperclass = getClass().getGenericSuperclass(); if (genericSuperclass instanceof ParameterizedType) { this.genericityType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0]; } else { this.genericityType = Object.class; }
Type: Java中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
getGenericSuperclass()获得带有泛型的父类: 获得带有泛型的父类。
ParameterizedType: 参数化类型,即泛型。
getActualTypeArguments:获取参数化类型的数组,泛型参数可能有多个
getActualTypeArguments()[0]得到了泛型的第一个参数T的类型,赋值给代表当前类泛型类型的成员变量
genericityType。如果不是参数化类型,比如在接收服务器回调的地方没有加泛型类型,那么我们就给
genericityType赋值Object的class对象。
genericityType是用来在后面作为Gson解析的类型参数的。
再来看看抽象方法:
public abstract void onResolve(String json); public abstract void onFailed(String err_code, String message);
聪明的你一定发现了没有
onSuccess(),别急,看到后面你就明白了。
onResolve()就是用来解析json的了,子类需要重写它来具体解析。
onFailed是错误回调。
2.2 针对刚才服务器对象封装的抽象子类
public abstract class ServerCallback<T, V> extends HttpCallback<T>{ @Override public void onResolve(String json) { boolean returnJson = false; if (genericityType instanceof Class) { switch (((Class) genericityType).getSimpleName()) { case "Object": case "String": returnJson = true; break; default: break; } } if (returnJson) { onSuccess((V) json); } else { T t = (new Gson()).fromJson(json, genericityType); if (t instanceof ServerCallbackModel) { ServerCallbackModel<V> callbackData = (ServerCallbackModel) t; V result = callbackData.getData(); if (callbackData.isSuccess()) { this.onSuccess(result); } else { onFailed(callbackData.getErr_code(), callbackData.getMessage()); } } else { onSuccess((V) t); } } } public void onFailed(String error_code, String error_message) { if (enableShowToast()) { Toast.makeText(HttpManager.mContext, error_message, Toast.LENGTH_SHORT).show(); } onFailure(error_code, error_message); } public abstract void onSuccess(V data); public abstract void onFailure(String error_code, String error_message); public boolean enableShowToast(){ return false; } }
首先,我们定义了一个抽象的带两个类型参数的泛型类,第一个参数是
Gson映射的外层对象,比如可以传入我们刚才定义的
ServerCallbackModel,第二个参数就是外层对象中的数据了,比如
ServerCallbackModel中的data。
然后来分析下类中的方法,先来看看非抽象的方法:
public void onResolve(String json)
这个方法用来解析服务器回调,参数json就是服务器回调的json字符串。
首先判断泛型类型
genericityType是不是
Class类型的,然后判断
genericityType的名字是否为
String或者
Object,是则直接在成功回调中传入json字符串。
如果不是,则用Gson将json解析出来,实参就是
genericityType。此时解析出来的类型如果是我们刚才定义的
ServerCallbackModel,如果服务器返回成功,那就将data返回,data的类型就是这个类的第二个类型参数,也是
onSuccess的形参类型,我们最终需要的数据。
如果服务器返回失败,会将错误传递给onFailed。
protected void onFailed(String error_code, String error_message)
这个方法主要是拦截错误,用于统一处理所有请求的错误。默认只判断是否需要直接弹toast显示错误信息。
public boolean enableShowToast()
我们可以考虑是否直接将错误信息弹窗提示出来,只需要重写
enableShowToast方法,返回
true即可。
再来看看抽象方法,这个就是我们最终在具体的业务层需要重写的方法了。
public abstract void onSuccess(V data);
服务器返回成功的信息后,数据会传递到这里。
public abstract void onFailure(String error_code, String error_message);
错误经过
onFailed拦截后,会传递到这里。
3 使用封装的回调
HttpCallback callback = new TmpCallback<ServerCallbackModel<User>,User>() { @Override public void onSuccess(User data) { } @Override public void onFailure(String error_code, String error_message) { } }; API.testGet(callback);
刚才你看到ServerCallback可能还不理解为什么这个泛型要有两个参数,看到这里你应该就秒懂了,其实服务器传回来的正确错误什么的,我们并不想每个调用的地方都去判断,我们这里想要的只是最终的数据。
本文的Demo地址是我的一个开源库,这个库已经经过了我们公司产品大量用户的考验,欢迎
star和
fork,也欢迎大家提
issue。
RetrofitClient: https://github.com/Jadyli/RetrofitClient
里面的封装基本都是按照本文的思路写的,当然也可以有所变化,比如有些接口没有success之类的,直接就是上数据,那就可以使用CommonCallback。
相关文章推荐
- Android使用GSON和FASTJSON解析服务器返回的JSON数据
- Android使用Gson解析JSON连接服务器实现客户端登陆功能
- java android使用Gson解析泛型json数据
- Android JSON数据格式的解析,与简单对象、带泛型的List和Map的转换,以及GSON的使用
- 解决android使用gson解析json字符串,并使用混淆编译方式打包apk遇到的问题
- Android中使用Gson解析JSON数据
- Android 使用Gson解析json用法
- 解决android使用gson解析json字符串,并使用混淆编译方式打包apk遇到的问题
- 【Android开发经验】超好用的json解析工具——Gson项目使用详解
- android中使用Gson解析普通json数据(致我的第一篇博文)
- Android中Json数据解析(二)--使用Gson、Jackson和FastJson解析Json数据
- Android中使用Gson解析JSON数据的两种方法
- Android中使用Gson解析JSON数据
- Android中Json数据解析(二)--使用Gson、Jackson和FastJson解析Json数据
- 【Android开发经验】比Gson解析速度快10倍!——Json解析神器Jackson使用介绍
- Android应用之——谷歌官方Json解析工具Gson的使用
- json 的解析-使用Android中的JSONObject和JSONArray解析json数据,gson中的JsonReader解析json数据
- Android 使用GSON解析JSON 并转换为JAVA对象
- Android中使用Gson解析JSON数据
- Android 编程下使用 Google 的 Gson 解析 Json