背景
感谢并参考[怪盗kidou]的《搞定Gson泛型封装》 。
上一篇《 Java基础--Android中泛型的应用(一)》介绍了泛型在Android开发中解析服务端回来json数据的使用,减少了许多冗余代码,但我们仍然不知道如何把泛型的类型传入给Gson的fromJson
方法里面,下面我们来看看:
想办法获取泛型类型
Gson为我们提供的TypeToken类,可以用于获取泛型类的类型:
Gson gson=new GsonBuilder().serializeNulls().create();
BaseEntity<LoginEntity> entity = gson.fromJson(response, new TypeToken<BaseEntity<LoginEntity>>() {}.getType());
对于List是这么解析的:
Gson gson=new GsonBuilder().serializeNulls().create();
BaseEntity<ListEntity<GoodsItem>> entity=gson.fromJson(response, new TypeToken<BaseEntity<ListEntity<GoodsItem>>>() {}.getType());
非常开心得知以上解析是可行的,但还不够好,需要进一步封装。于是我们将该解析方法统一封装为以下方法:
public <T> BaseEntity<T> fromJsonObject(String jsonStr, Class<T> clazz) {
Type type = new TypeToken<BaseEntity<T>>(){}.getType();
return mGson.fromJson(jsonStr, type);
}
但发现出错了,原来这里的TypeToken并不会对T进行解析,解析出来的结果只会是BaseEntity<T>
前面我们都是直接使用LoginEntity
,所以没有发现这个问题,参考《搞定Gson泛型封装》 ,我们最后只能使用ParameterizedType接口,如下:
public class ParameterizedTypeImpl implements ParameterizedType {
private final Class raw;
private final Type[] args;
public ParameterizedTypeImpl(Class raw, Type[] args) {
this.raw = raw;
this.args = args != null ? args : new Type[0];
}
@Override
public Type[] getActualTypeArguments() {
return args;
}
@Override
public Type getRawType() {
return raw;
}
@Override
public Type getOwnerType() {
return null;
}
}
对Gson的封装
我们定义了一个GsonHelper单例类,以方便各种同一的操作:
/**
* Created by fangzhengyou on 16/9/23.
* json数据统一在这里做解析
*/
public class GsonHelper {
private static GsonHelper instance = null;
private static final Object mLock = new Object();
private static Gson mGson = null;
public static GsonHelper getInstance() {
synchronized (mLock) {
if (instance == null) {
instance=new GsonHelper();
mGson = new GsonBuilder().serializeNulls().create();
}
return instance;
}
}
private GsonHelper() {
}
// 处理 data 为 null 的情况
public Result fromJsonNull(String jsonString, Class<BaseEntity> clazz) {
return mGson.fromJson(jsonString, clazz);
}
// 处理 data 为 object 的情况
public <T> BaseEntity<T> fromJsonObject(String jsonStr, Class<T> clazz) {
Type type = new ParameterizedTypeImpl(BaseEntity.class, new Class[]{clazz});
return mGson.fromJson(jsonStr, type);
}
// 处理 data 为 array 的情况
public <T> BaseEntity<ListEntity<T>> fromJsonArray(String jsonStr, Class<T> clazz){
// 生成ListEntity<T> 中的 Type
Type listType = new ParameterizedTypeImpl(ListEntity.class, new Class[]{clazz});
// 根据ListEntity<T>生成的,再生出完整的BaseEntity<ListEntity<T>>
Type type = new ParameterizedTypeImpl(BaseEntity.class, new Type[]{listType});
return mGson.fromJson(jsonStr, type);
}
}
那么以后我们要解析只需要按照原来的格式即可:
BaseEntity<ListEntity<GoodsItem>> entity = mGsonHelper.fromJsonArray(response,GoodsItem.class);