Android-Gson源码实现

1.fromJson

public  T fromJson(String json, Class classOfT) throws JsonSyntaxException {
    Object object = fromJson(json, (Type) classOfT);
    return Primitives.wrap(classOfT).cast(object);
}

这个方法的实现,是调用了传入Type的fromJson

public  T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
    if (json == null) {
        return null;
    }
    StringReader reader = new StringReader(json);
    T target = (T) fromJson(reader, typeOfT);
    return target;
}

这里调用的fromJson是传入了一个Reader对象

public  T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    JsonReader jsonReader = newJsonReader(json);
    T object = (T) fromJson(jsonReader, typeOfT);
    assertFullConsumption(object, jsonReader);
    return object;
}

这里调用的fromJson是传入了JsonReader对象,所有的fromJson都会调用下面这个

public  T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    boolean isEmpty = true;
    boolean oldLenient = reader.isLenient();
    reader.setLenient(true);
    try {
        reader.peek();
        isEmpty = false;
        // 将传入的Type实例封装成一个TypeToken实例
        TypeToken typeToken = (TypeToken) TypeToken.get(typeOfT);
        // 根据对应的TypeToken,从typeTokenCache这个Map缓存中取出对应的TypeAdapter
        TypeAdapter typeAdapter = getAdapter(typeToken);
        // 调用对应的TypeAdapter的实现类的read方法,将对应的JsonReader封装Json字符串之后的对象解析转换成对应的实体类
        T object = typeAdapter.read(reader);
        return object;
    } catch (EOFException e) {
        /*
        * For compatibility with JSON 1.5 and earlier, we return null for empty
        * documents instead of throwing.
        */
        if (isEmpty) {
            return null;
        }
        throw new JsonSyntaxException(e);
    } catch (IllegalStateException e) {
        throw new JsonSyntaxException(e);
    } catch (IOException e) {
        // TODO(inder): Figure out whether it is indeed right to rethrow this as       JsonSyntaxException
        throw new JsonSyntaxException(e);
    } finally {
        reader.setLenient(oldLenient);
    }
}

在这里,是通过TypeAdapter对象获取到了返回的Object对象,而TypeAdapter是通过getAdapter方法得到的:

  @SuppressWarnings("unchecked")
  public  TypeAdapter getAdapter(TypeToken type) {
    // 1.首先尝试从Gson中的Map缓存中取出对应的TypeAdapter实现类对象
    TypeAdapter cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
    if (cached != null) {
      return (TypeAdapter) cached;
    }

    // 2.
    // calls是一个Gson内部的ThreadLocal对象,是一个ThreadLocal, FutureTypeAdapter>>类型的,
    // 其内部存的是一个Map集合,而FutureTypeAdapter是TypeAdapter的代理类对象
    // 使用ThreadLocal来缓存FutureTypeAdapter对象,是本地防止getAdapter()的重入调用
    // 其实就是避免无限递归导致一直创建TypeAdapter,最终因为无限递归导致栈溢出的问题
    Map, FutureTypeAdapter> threadCalls = calls.get();
    boolean requiresThreadLocalCleanup = false;
    if (threadCalls == null) {
      threadCalls = new HashMap, FutureTypeAdapter>();
      calls.set(threadCalls);
      requiresThreadLocalCleanup = true;
    }

    // 3.如果在ThreadLocal中的Map中找到了TypeToken对应的FutureTypeAdapter,则直接返回
    // FutureTypeAdapter是一个委托类,其实就是代理类,内部保存TypeToken对应的TypeAdapter实例
    // FutureTypeAdapter也是继承自TypeAdapter
    FutureTypeAdapter ongoingCall = (FutureTypeAdapter) threadCalls.get(type);
    if (ongoingCall != null) {
      return ongoingCall;
    }

    try {
      //创建FutureTypeAdapter,保存在ThreadLocal对象中
      FutureTypeAdapter call = new FutureTypeAdapter();
      threadCalls.put(type, call);

      for (TypeAdapterFactory factory : factories) {
        // 在这里可能会发生无限递归的情况,即在new Adapter(constructor, getBoundFields(gson, type, raw));
        // getBoundFields方法中,会调用createBoundField方法封装每个Field,这个时候就会获取每个Field的TypeAdapter
        // 这里递归的主要原因就是create内部创建Adapter的时候,会调用getBoundFields方法,其内部又会调用createBoundField方法,
        // 在createBoundField方法中又会调用Gson.getAdapter,这样又递归到了Gson.getAdapter,而使用了一个ThreadLocal,
        // 因为已经提前put了,递归调用的时候,第二次同样的类型执行到上面就会通过return ongoingCall;返回,而不会执行到这里继续递归
        // 使用ThreadLocal的目的就是在递归调用getAdapter的时候,出现TypeToken相同的情况下,在第一次递归时就提前返回,然后在使用外部类型的TypeAdapter
        TypeAdapter candidate = factory.create(this, type);
        if (candidate != null) {
          // 将通过TypeAdapterFactory.create创建的TypeAdapter委托给对应的FutureTypeAdapter对象
          call.setDelegate(candidate);
          // 缓存对应的TypeAdapter
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }
      throw new IllegalArgumentException("GSON cannot handle " + type);
    } finally {
      threadCalls.remove(type);

      if (requiresThreadLocalCleanup) {
        calls.remove();
      }
    }
  }

上面getAdapter代码中会遍历存储TypeAdapterFactory的factories,寻找对应的TypeAdapterFactory实例,比如返回一个Bean类的对象的话,则会调用ReflectiveTypeAdapterFactory,通过这个Factory.create创建对应的TypeAdapter实例。

2.属性说明

  private final ThreadLocal, FutureTypeAdapter>> calls
      = new ThreadLocal, FutureTypeAdapter>>();

calls是一个ThreadLocal,这个ThreadLocal缓存了一个Map集合,通过对应的TypeToken在当前线程中取出对应的FutureTypeAdapter,然后返回。增加一个ThreadLocal缓存的目的就是为了避免递归查找导致无限创建TypeAdapter实例而出现栈溢出。
比如:

public class Article {
    public Article article;
    .....
    .....
    .....
    
    
}

在这个例子中,一个Article,其内部有一个属性,也是Article类型的,如果不使用ThreadLocal,那么就会出现无限递归创建对应的TypeAdapter实例进行解析。而使用委托类,则会通过委托类对象,其内部调用已经创建的TypeAdapter进行read。这样就会复用同一个TypeAdapter实例。
可以参考下面的文章中的内容:

https://www.jianshu.com/p/aef252db9869

3.ReflectiveTypeAdapterFactory.BoundField相关

在ReflectiveTypeAdapterFactory.create方法如下:

  @Override public  TypeAdapter create(Gson gson, final TypeToken type) {
    Class raw = type.getRawType();

    if (!Object.class.isAssignableFrom(raw)) {
      return null; // it's a primitive!
    }

    ObjectConstructor constructor = constructorConstructor.get(type);
    // 调用ReflectiveTypeAdapterFactory.getBoundFields方法返回一个Map集合,
    // 这个Map集合的key其实就是Field的name,而BoundField其实就是根据对应的字段类型、字段名称等进行封装委托
    return new Adapter(constructor, getBoundFields(gson, type, raw));
  }
  private Map getBoundFields(Gson context, TypeToken type, Class raw) {
    Map result = new LinkedHashMap();
    if (raw.isInterface()) {
      return result;
    }

    Type declaredType = type.getType();
    // 如果真实类型是Object类型,则结束循环
    while (raw != Object.class) {
      // 获取该类型的所有内部属性,getDeclaredFields()方法是获取本类型,不包括父类的所有属性(包括私有属性)
      Field[] fields = raw.getDeclaredFields();
      // 遍历所有字段
      for (Field field : fields) {
        boolean serialize = excludeField(field, true);
        boolean deserialize = excludeField(field, false);
        if (!serialize && !deserialize) {
          continue;
        }
        field.setAccessible(true);
        // 获取字段的类型
        Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
        // 获取字段名称,因为通过Gson注解可以给一个字段设置多个name
        List fieldNames = getFieldNames(field);
        BoundField previous = null;
        for (int i = 0, size = fieldNames.size(); i < size; ++i) {
          String name = fieldNames.get(i);
          // 只对默认名称进行序列化数据
          if (i != 0) serialize = false; // only serialize the default name
          // 创建BoundField
          BoundField boundField = createBoundField(context, field, name,
              TypeToken.get(fieldType), serialize, deserialize);
          // 替换Map中已有的value
          BoundField replaced = result.put(name, boundField);
          if (previous == null) previous = replaced;
        }
        if (previous != null) {
          // 如果previous不为null,说明Map中在根据name创建BoundField的时候,已经有一个BoundField
          // 这样的情况说明一个name有了两个BoundField,则说明一个类中出现两个字段名相同的字段
          throw new IllegalArgumentException(declaredType
              + " declares multiple JSON fields named " + previous.name);
        }
      }
      type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
      // 获取父类型,继续循环,直到父类型为Object为止。
      // 这样做的目的就是为了Bean类有继承的情况,能对父类属性进行解析。
      raw = type.getRawType();
    }
    return result;
  }

在通过ReflectiveTypeAdapterFactory.create创建TypeAdapter实例的时候,通过getBoundFields创建一个Map集合,主要就是为了对类的所有属性进行封装。

  // 根据Field创建BoundField,并且封装Field的读写操作
  private ReflectiveTypeAdapterFactory.BoundField createBoundField(
      final Gson context, final Field field, final String name,
      final TypeToken fieldType, boolean serialize, boolean deserialize) {
    // 判断是否是基本数据类型
    final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
    // special casing primitives here saves ~5% on Android...
    JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
    TypeAdapter mapped = null;
    if (annotation != null) {
      mapped = jsonAdapterFactory.getTypeAdapter(
          constructorConstructor, context, fieldType, annotation);
    }
    final boolean jsonAdapterPresent = mapped != null;
    // Gson尝试获取该Field字段类型的TypeAdapter
    // 这里的context其实就是Gson实例,这里其实又是调用了Gson.getAdapter
    if (mapped == null) mapped = context.getAdapter(fieldType);

    // 使用final,是便于内部类使用
    final TypeAdapter typeAdapter = mapped;
    return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
      @SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree
      @Override void write(JsonWriter writer, Object value)
          throws IOException, IllegalAccessException {
        Object fieldValue = field.get(value);
        TypeAdapter t = jsonAdapterPresent ? typeAdapter
            : new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
        t.write(writer, fieldValue);
      }
      // 执行Json数据的读取解析操作,然后转换成Object对象,通过Field.set,给对应的字段设置value值。
      @Override void read(JsonReader reader, Object value)
          throws IOException, IllegalAccessException {
        // 通过该属性的类型对应的TypeAdapter尝试读取json串
        //如果是基础类型,则直接读取,
        //如果是复合类型则递归之前的流程
        // 因为在Gson.fromJson方法中,最终就是通过调用typeAdapter.read进行json串解析
        // 而这里是又被typeAdapter.read调用,而这里又调用了typeAdapter.read(reader);
        // 其实就是一个递归调用流程,即在typeAdapter.read内部调用了typeAdapter.read(reader);
        Object fieldValue = typeAdapter.read(reader);
        if (fieldValue != null || !isPrimitive) {
          field.set(value, fieldValue);
        }
      }
      @Override public boolean writeField(Object value) throws IOException, IllegalAccessException {
        if (!serialized) return false;
        Object fieldValue = field.get(value);
        return fieldValue != value; // avoid recursion for example for Throwable.cause
      }
    };
  }

4.ReflectiveTypeAdapterFactory.read

找到对应的TypeAdapter之后,就会调用对应的read方法。以反射方式实现为例子:

主要是借助了ReflectiveTypeAdapterFactory,每个TypeAdapter其实都是通过对应的Factory的create方法获取到的。而ReflectiveTypeAdapterFactory中有一个内部类,就是继承了TypeAdapter类

public static final class Adapter extends TypeAdapter {
    // 用于反射获取对象
    private final ObjectConstructor constructor;

    private final Map boundFields;

    Adapter(ObjectConstructor constructor, Map boundFields) {
        this.constructor = constructor;
        this.boundFields = boundFields;
    }

    @Override public T read(JsonReader in) throws IOException {

        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }

        T instance = constructor.construct();

        try {

            in.beginObject();

            while (in.hasNext()) {
                String name = in.nextName();
                BoundField field = boundFields.get(name);
                // 判断boundFields中对应的字段名称是否为空,如果为空则跳过
                // 这就是为什么json串中有更多字段的数据,可以使用更少属性的类来解析,因为这里会跳过
                if (field == null || !field.deserialized) {
                    in.skipValue();
                } else {
                    // 调用BoundField.read方法,其内部会调用TypeAdapter.read
                    field.read(in, instance);
                }
            }
        } catch (IllegalStateException e) {
            throw new JsonSyntaxException(e);
        } catch (IllegalAccessException e) {
            throw new AssertionError(e);
        }

        in.endObject();
        return instance;
    }

    @Override public void write(JsonWriter out, T value) throws IOException {

        if (value == null) {
            out.nullValue();
            return;
        }

        out.beginObject();
        try {
            for (BoundField boundField : boundFields.values()) {

                if (boundField.writeField(value)) {
                    out.name(boundField.name);
                    boundField.write(out, value);
                }
            }
        } catch (IllegalAccessException e) {
            throw new AssertionError(e);
        }
        out.endObject();
    }

}

Gson解析中,使用ReflectiveTypeAdapterFactory的解析过程:


image.png

5.使用TypeToken需要为什么要使用匿名内部类的方式?

new TypeToken(){}.getType(),如果这里不采用创建匿名内部类的方式去获取Type,而是new TypeToken().getType(),那么这样创建的一个对象,在经过编译为.class的时候,其泛型类型就会因为类型擦除而变成了Object,这样就没办法获取到准确的Type。
而在这里使用{},其实就是创建匿名内部类对象,在创建匿名内部类对象,那么其实就可以认为是创建了一个新的类,就是将旧的TypeToken类的中的泛型T都替换成了BaseResponse的新类。这个新类,其实就可以认为是TypeToken中的泛型T都为BaseResponse的一个新类,而不是使用T了。这样,在编译成.class文件的时候,就不会因为泛型擦除而出现T变成Object,而是编译成.class之后,其实就是T都是BaseResponse类型。
匿名内部类对象,其实可以认为是创建了一个新的匿名内部类,然后使用这个匿名内部类来创建了一个对象。

6.Excluder排序器

主要是为了处理一些不需要序列化和不需要反序列化的一些字段的。

(2)返回list集合的fromJson

public  TypeAdapter getAdapter(TypeToken type) {

    // type的值是java.util.list<类路径>

    TypeAdapter cached = typeTokenCache.get(type);

    if (cached != null) {
        return (TypeAdapter) cached;
    }

    Map, FutureTypeAdapter> threadCalls = calls.get();
    boolean requiresThreadLocalCleanup = false;
    if (threadCalls == null) {
        threadCalls = new HashMap, FutureTypeAdapter>();
        calls.set(threadCalls);
        requiresThreadLocalCleanup = true;
    }

    // the key and value type parameters always agree
    FutureTypeAdapter ongoingCall = (FutureTypeAdapter)     threadCalls.get(type);

    if (ongoingCall != null) {
        return ongoingCall;
    }

    try {
        FutureTypeAdapter call = new FutureTypeAdapter();
        threadCalls.put(type, call);
        for (TypeAdapterFactory factory : factories) {
            TypeAdapter candidate = factory.create(this, type);
            if (candidate != null) {
                call.setDelegate(candidate);
                typeTokenCache.put(type, candidate);
                return candidate;
            }
        }
        throw new IllegalArgumentException("GSON cannot handle " + type);
    } finally {  
        threadCalls.remove(type);
        if (requiresThreadLocalCleanup) {
            calls.remove();
        }
    }
}

而返回List集合,是通过CollectionTypeAdapterFactory这个类里面的内部类来实现的:

private static final class Adapter extends TypeAdapter> {

    private final TypeAdapter elementTypeAdapter;

    private final ObjectConstructor> constructor;

    public Adapter(Gson context, Type elementType,

    TypeAdapter elementTypeAdapter,

    ObjectConstructor> constructor) {
        this.elementTypeAdapter = new TypeAdapterRuntimeTypeWrapper(context, elementTypeAdapter, elementType);
        this.constructor = constructor;
    }

    @Override public Collection read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }

        Collection collection = constructor.construct();
        in.beginArray();
        while (in.hasNext()) {
            E instance = elementTypeAdapter.read(in);
            collection.add(instance);
        }

        in.endArray();  
        return collection;
    }

    @Override public void write(JsonWriter out, Collection collection) throws IOException {

        if (collection == null) {
            out.nullValue();
            return;
        }

        out.beginArray();
        for (E element : collection) {
            elementTypeAdapter.write(out, element);
        }  
        out.endArray();
    }
}

在内部类的Adapter中都会有一个read方法,而read方法中,会在内部调用elementTypeAdapter这个类的read方法,而这个类的read方法,其实是调用的TypeAdapterRuntimeTypeWrapper的read方法,而TypeAdapterRuntimeTypeWrapper的read方法是调用了ReflectiveTypeAdapterFactory的内部类Adapter的read方法,也就是通过反射拿到一个个的对象。说明List的形式其实就是通过反射拿到一个Connection对象,再通过反射拿到一个个的对象,然后将这些对象放到Connection中。Map的方式其实是类似的。

(3)返回Map集合

返回Map集合中,Gson.java类中的getAdapter方法中的TypeAdapter candidate = factory.create(this, type);最终是调用的MapTypeAdapterFactory类的create方法。而在这里,会分别创建两个TypeAdapter,也就是KeyAdapter和ValueAdapter,这两个Adapter都是ObjectTypeAdapter的实例对象。

如果key是一个String、int、boolean这样的类型的,则KeyTypeAdapter对象其实就是从TypeAdapters中的对应的TypeAdapter的实现类。而value如果是Object,那么则是通过ReflectiveTypeAdapterFactory的静态final内部类Adapter返回对应的Object的,其实就是通过反射的方式返回的。

JsonReader解析:

(1)beginObject()

int peeked = PEEKED_NONE;

public void beginObject() throws IOException {

    int p = peeked;

    if (p == PEEKED_NONE) {

        p = doPeek();

    }

    if (p == PEEKED_BEGIN_OBJECT) {

        push(JsonScope.EMPTY_OBJECT);

        peeked = PEEKED_NONE;

    } else {

        throw new IllegalStateException("Expected BEGIN_OBJECT but was " + peek() +   locationString());

    }

}

peeked是个很重要的变量,默认值为PEEKED_NONE。在上面的方法中,调用了一个方法doPeek(),这个类可以说是JsonReader类的核心方法之一。

你可能感兴趣的:(Android-Gson源码实现)