Android 中 Json 的二次解析

1,965 阅读2分钟

介绍

先写这篇文章的缘由吧,之前做项目的时候,在搭建框架之处,我想了一个自认为比较聪明的办法来解析服务器传回的数据:

public class Result implements Serializable {

    private String status;

    private int count;

    private T data;

    private String message;


    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

这是一个用于接收服务器传回的Json的通用范型实体类,我的思路是在每个需要进行网络解析的地方传入不同的范型,利用FastJson对不同的网路请求结果进行一次解析,大致代码如下:

String response = new String(responseBody);
   Result result = JSON.parseObject(response, 	new TypeReference>() {
      

虽然美好的愿望实现了,但是并没有持续多久,没有几次它就出错了。而且问题很奇葩,主要原因是传范型引起的,我在FastJson的GitHub的Issue中也发现了这个问题,但是作者并没有给出结果。

Issue链接:github.com/alibaba/fas…

google了很久并未解决,项目催的又紧,只好尝试使用Gson尝试,居然没这问题,然后这个问题就这么混过去了。

之后空下来了,想通过二次解析来实现之前利用FastJson一次解析出现的问题。其实就是将之前出错的data部分当成Json字符串,这样当status异常的时候就无需解析了,也节省了不必要的操作。

ParameterizedType

Type直接子接口; 
ParameterizedType,GenericArrayType,TypeVariable和WildcardType四种类型的接口

  • ParameterizedType: 表示一种参数化的类型,比如Collection
  • GenericArrayType: 表示一种元素类型是参数化类型或者类型变量的数组类型
  • TypeVariable: 是各种类型变量的公共父接口
  • WildcardType: 代表一种通配符类型表达式,比如?, ? extends Number, ? super Integer【wildcard是一个单词:就是“通配符”】

ParameterizedType接口类型的含义:表示参数化类型<>中的实际类型。

源码声明:Type[] getActualTypeArguments();
【注意】无论<>中有几层<>嵌套,这个方法仅仅脱去最外层的<>之后剩下的内容就作为这个方法的返回值。

实现过程

在某个场景的基类中传入范型的参数T

例如:

public sabstract BaseRecycleListFragment{

...

}

在基类的网络数据的回调方法中进行二次解析

例如:

Result result = JSON.parseObject(responseBody,Result.class);

if(result!=null && )

Type type  = BaseRecycleListFragment.this.getClass().getGenericSuperclass();

if(type instanceof ParameterizedType){
	Type poClass = (ParameterizedType).getActualTypeArguments()[0];
	if(poClass!=null){
		List data = JSON.parseArray(JSON.toJSONString(result.getData()),(Class poClass));
		...
		...
		...
	}
}

上面的代码就是一个二次解析一个列表的例子,首先判断status是否正确,正确的话进行二次解析。

这样就避免了1次解析出错的情况了。