Gson解析泛型
解析方式:
一、
应用场景:除接口外其他类,获取泛型类型,进行解析。混淆时需要keep 此类。
泛型Type/Class获取
Type mType = mBaseEntity.getClass().getGenericSuperclass();
Type nType= ((ParameterizedType) mType ).getActualTypeArguments()[0];
Class mClass = mBaseEntity.getResultType();
解析
T mResponse = new Gson().fromJson(body, mClass);
二、
应用场景:接口中的泛型,获取泛型类型,进行解析。混淆时需要keep 此接口。
接口
public interface CssCallback<T> {
void onResponse(T mResponse);
void onFailure(Call<?> call, Throwable t);
}
泛型Type/Class获取
//Class<T> tClass=null;//根据当前类获取泛型的
TypeType typeOfT=null;
Type[] interfacesTypes = null!=mCallback ? mCallback.getClass().getGenericInterfaces() : null;
if(null!=interfacesTypes){
for(Typet: interfacesTypes){
Type[]genericType2=((ParameterizedType)t).getActualTypeArguments();
//接口有几个泛型参数,genericType2size一般就为几。
for(Typet2: genericType2){
//tClass=(Class<T>)t2;
typeOfT=t2;
}
}
}
解析
/*if(null!=tClass){
mResponse=(T)newGson().fromJson(body,tClass);
}*/
if(null!=typeOfT){
T mResponse=newGson().fromJson(body, typeOfT);
}
三、
应用场景:均可使用,但混淆时无法使用,无论是否忽略类接口泛型混淆都不行。
泛型类型获取
Class claz=null;
Method[] ms = null != mCallback ? mCallback.getClass().getDeclaredMethods(): null;
if(null!=ms){
for(Methodm: ms){
if(!TextUtils.equals(null != m ? m.getName(): "","onResponse"))
continue;
Class[] paramTypes = null != m ? m.getParameterTypes(): null;
if(null!=paramTypes
&¶mTypes.length==1
&&BaseEntity.class.isAssignableFrom(paramTypes[0])){
claz=paramTypes[0];
if(!claz.isAssignableFrom(CssCallback.class)){
break;
}
}
}
}
解析
if(null!=claz){
T mResponse=(T)newGson().fromJson(body,claz);
}
总结:
因为Android release打包时正常都会对代码进行混淆,所以方法三基本可以废弃,在方法一和方法二中自由选择,注意使用场景。两个方法的本质区别是getGenericSuperclass()
和getGenericInterfaces()
。
接口中泛型混淆问题
public interface CssCallback<T> {
void onResponse(T mResponse);
void onFailure(Call<?> call, Throwable t);
}
如上接口包含有泛型,混淆时添加接口keep,泛型keep,使用方法三获取泛型类型并解析,但泛型始终会被定义成Object,解析失败。
混淆配置
# 避免混淆泛型
-keepattributes Signature
外部接口
-keep public interface com.XXX.XXX.XXX.CssCallback{ *; }
内部接口
-keep public interface com.XXX.XXX.XXX.RequestManager$CssCallback{ *; }