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);
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) {
}
};
网友评论