AndroidGson解析Json数据过程和如何⾃定义解析规则(中)根据上篇⽂章,我们要把解析⼊⼝⾛我们⾃⼰的流程,我们需要⼀个⾃⼰的 GsonConverFactory 但是⼜不想写其他代码,只想改关键地⽅,我们肯定会想到直接继承 GsonConverFactory 但是很遗憾,这个类带final 不能被继承,所以,我们可以直接把这个类复制⼀份处理,⼀步⼀步的⾃定义我们⾃⼰的适配器;我们的⽬标就是把Object类型和Collect类型解析⾃定义
通过源码发现,⼤部分类都是带final关键字,不能被继承,所以我们只能复制⼀份出来,没办法。
⾸先把 CollectionTypeAdapterFactory复制出来 然后缺啥复制啥出来然后ReflectiveTypeAdapterFactory也是如此
经过⼀番复制,最后需要复制出的⽂件如下:
我们到其对应的 WCollectionTypeAdapterFactory对应的read⽅法,按照如下更改
@Override
public Collection<E> read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
if (peek == JsonToken.NULL) {
struct();//改动
} else if (peek != JsonToken.STRING) {//改动
Collection<E> collection = struct();
in.beginArray();
while (in.hasNext()) {
E instance = ad(in);
collection.add(instance);
}
return collection;
}
//必须要跳过不能解析的value,防⽌出现{arr:""}这种情况,指针停留在双引号之间,导致解析下⼀个name时出现空⽽爆粗
struct();
}
同理,对Object类型的⽂件WReflectiveTypeAdapterFactory解析修改如下:
@Override
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
return null;
}
//如果是字符串,说明没有正确的数据不能继续往下⾛,直接返回new的对象
if (in.peek() == JsonToken.STRING) {
struct();
}
T instance = struct();
try {
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
BoundField field = (name);
if (field == null || !field.deserialized) {
in.skipValue();
} else {
}
}
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
return instance;
}
,核⼼部分已完成修改,接下来需要把所有的改动应⽤⾄retrofit2中,我们到复制出来的WGsonConverFactory类,这个类作为我们
新的转换类,其内部我们需要做点修改,把我们上⾯复制的两个WReflectiveTypeAdapterFactory和WCollectionTypeAdapterFactory
注册到Gson实例中,把原来的解析器替换成我们的解析器,如下:
public class WGsonConverFactory extends Converter.Factory {
private static final String TAG = "WGSON";
//主要改动在这⾥
public static WGsonConverFactory create() {
GsonBuilder gsonBuilder = new GsonBuilder();
//通过反射获取各种属性为其更换类型处理器
try {
Class builder = Class();
Field f = DeclaredField("instanceCreators");
f.setAccessible(true);
Map<Type, InstanceCreator<?>> val = (Map<Type, InstanceCreator<?>>) f.get(gsonBuilder);//得到此属性的值
Field namingStra = DeclaredField("fieldNamingPolicy");
namingStra.setAccessible(true);
FieldNamingStrategy fieldNamingPolicy = (FieldNamingStrategy) (gsonBuilder);
Field filedExcluder = DeclaredField("excluder");
filedExcluder.setAccessible(true);
Excluder excluder = (Excluder) (gsonBuilder);
//这个类由于反射拿不到数据,所以也把他复制出来,直接new即可
JsonAdapterAnnotationTypeAdapterFactory jsonAdapterAnnotationTypeAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(new Construc
JsonAdapterAnnotationTypeAdapterFactory jsonAdapterAnnotationTypeAdapterFactory = new Json
AdapterAnnotationTypeAdapterFactory(new C
//注册数组的处理器
//注册Object;类型处理器
} catch (NoSuchFieldException e) {
Log.e(TAG, "可能出现某个字段丢失导致多个类型适配器反射注册失败,这可能会影响之后的json数据解析 ", e);
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return ate());
}
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static WGsonConverFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new WGsonConverFactory(gson);
}
private final Gson gson;
private WGsonConverFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
Log.w("TYPE", "类型是 " + TypeName());//
TypeAdapter<?> adapter = (type));
return new WGsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = (type));
return new WGsonRequestBodyConverter<>(gson, adapter);
}
}
最后,将其注册到retrofit2,替换原来的GsonConverFactory,使⽤⽅法如下:
this.host = Instance().getHostPort();
File cacheDirectory = new File(context
.getCacheDir().getAbsolutePath(), "HttpCache");
builder = new OkHttpClient.Builder();
builder.addInterceptor(new HttpGlobalIntercepter());
android retrofit
builder.writeTimeout(TIMEOUT, TimeUnit.SECONDS);
builder.cache(new Cache(cacheDirectory, 10 * 1024 * 1024));
userServiceAPI = new Retrofit.Builder()
.client(builder.build())
.baseUrl(this.host).ate())//使⽤我们⾃⼰的转换器
.ate())
.build()
.create(GsonTestAPI.class);
测试结果:
WCollectionTypeAdapterFactory 能正常使⽤,但是WReflectiveTypeAdapterFactory 这个类不能正常使⽤,估计由于JsonAdapterAnnotationTypeAdapterFactory这个类在Gson中,然⽽WReflectiveTypeAdapterFactory初始化需要⽤到他,存在先后顺序ate()-->Gson初始化产⽣JsonAdapterAnnotationTypeAdapterFactory,初始化ReflectiveTypeAdapterFactory-->add 到Gson中,但是注册⾃定义解析器时需要在Gson初始化前,所以⽆法替换Gson中ReflectiveTypeAdapterFactory

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。