使用Gson转化成实体类中的一个方法,传的参数是 Type 对象。
fromJson(String json, Type typeOfT)
关于获取Type对象,我知道的有两种:
Type type = new TypeToken<T>() {}.getType();
和
Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
一开始在一个抽象类中,通过反射的方法获取Type对象,实体类用泛型代替,然后将该抽象类作为参数,传入具体的实体类。
注意,这里不能用第一种获取Type对象的方法,否则会报类型强转异常。
com.google.gson.internal.LinkedTreeMap cannot be cast to Basebean
使用第二种获取Type对象方法,具体代码:
public abstract class RequestCallback<T> extends Callback<T> {
public RequestCallback(){
}
public T parseNetworkResponse(Response response, int i) throws Exception {
String string = response.body().string();
Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return new Gson().fromJson(string, type);
}
}
Api.imQueryGroups(imsCookie, userId, new RequestCallback<BaseBean<List<GroupItemBean>>>() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(BaseBean<List<GroupItemBean>> baseBean, int i) {
}
});
这样就能在使用网络请求时,返回我们想要的实体类结果了。
PS:
如果对parseNetworkResponse()方法返回的实体具体化,就不会出现问题。就不需要创建一个子类去继承Callback了。
Api.imQueryGroups(imsCookie, userId, new Callback<BaseBean<List<GroupItemBean>>>() {
@Override
public BaseBean<List<GroupItemBean>> parseNetworkResponse(Response response, int i) throws Exception {
Type type = new TypeToken<BaseBean<List<GroupItemBean>>>() {}.getType();
return new Gson().fromJson(response.body().string(), type);
}
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(BaseBean<List<GroupItemBean>> baseBean, int i) {
}
});
但是这样的话,每次获取服务器返回的数据,都得写一遍Gson的实体类转化。做重复的事情是多么的无意义啊,于是我决定另寻办法。
网上找了好久都没解决方法,但是搜到了“泛型擦除”,结合自身问题,我觉得很可能就出现在这里。
泛型擦除:编译时,泛型类型会改为Object。
那么,第一种方法获取到的泛型是Object,Gson无法转化成相对应的实体类报错。
最后改用了第二种获取Type对象的方法,这种方法没有使用到泛型,最终编译成功,数据解析也正常。
参考:
http://blog.csdn.net/gengv/article/details/5178055
https://www.cnblogs.com/baiqiantao/p/7475477.html