日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android—Gson原理解析

發布時間:2023/12/18 Android 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android—Gson原理解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JsonElement

  • 抽象類
  • 代表json串的某一個元素
  • 某一個元素:
    • JsonObject
    • JsonArray
    • JsonPrimitive(基本類型)
    • JsonNull

JsonElement的四個子類

  • JsonObject、JsonArray、JsonPrimitive、JsonNull

JsonPrimitive?

該類對Java的基本類型及其對應的對象類進行了封裝(短整長,單精雙精,字符<表示為單字符字符串>,布爾)

Gson對象的產生

通過new Gson()方式

?通過這種方式創建的Gson對象,將用Java的反射機制來完成json的解析,將大量默認的TypeAdapterFactory添加到factories中,生成默認的Gson對象

通過GsonBuilder的方式

TypeAdapter:該類的作用就是把json串封裝成你指定的Java對象

通過GsonBuilder注冊TypeAdapter,并把TypeAdapter封裝成TypeAdpterFactory對象

將封裝成的TypeAdapterFactory通過GsonBuilder的create傳入Gson對象中并返回

調用gson.fromJson方法,調用getTypeAdapter方法返回你自定義的Adapter

下面解析new?Gson()方式的序列化過程

String json = "{ \"name\":\"java書籍\", \"authors\":[\"Jerry\",\"Tom\"]}"; Book book = new Gson().fromJson(json, Book.class); String s = new Gson().toJson(book);public class Book implements Serializable {private String name;private ArrayList<String> authors;public Book(String name, ArrayList<String> authors) {this.name = name;this.authors = authors;} }

反序列化過程

public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {boolean isEmpty = true;// 接受不符合規定的json變量的值boolean oldLenient = reader.isLenient();//強制設置為接受reader.setLenient(true);try { //此處相當于調用了一次 JsonReader 中的 doPeek() 方法,返回下一個令牌的類型而不消耗它,設置當前令牌reader.peek();isEmpty = false;//TypeToken 本質上是 Class 的增強封裝類TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);//根據要轉化的實體類型,獲取相應的適配器TypeAdapter<T> typeAdapter = getAdapter(typeToken);//通過適配器生成實體類T object = typeAdapter.read(reader);return object;} catch (EOFException e) {.......}}

可以看到最終結果是adapter的read方法返回了我們需要的對象。
先看 getAdapter (typeToken) 方法:

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {// 先判斷緩存TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);if (cached != null) {return (TypeAdapter<T>) cached;}Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();boolean requiresThreadLocalCleanup = false;if (threadCalls == null) {threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();calls.set(threadCalls);requiresThreadLocalCleanup = true;}// the key and value type parameters always agreeFutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);if (ongoingCall != null) {return ongoingCall;}try {FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();threadCalls.put(type, call);//這里是重點,factories 是構建gson對象時候添加的類型適配器工廠值?for (TypeAdapterFactory factory : factories) {//循環尋找可以處理該類型的factory ,factory.create()很重要TypeAdapter<T> candidate = factory.create(this, type);if (candidate != null) {call.setDelegate(candidate);typeTokenCache.put(type, candidate);return candidate;}}throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type); }TypeAdapter<T> candidate = factory.create(this, type);根據type獲取相應的typeAdapter , 然后返回,new Gson()的話,在構造函數會給添加許多的adpter, Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,int timeStyle, List<TypeAdapterFactory> builderFactories,List<TypeAdapterFactory> builderHierarchyFactories,List<TypeAdapterFactory> factoriesToBeAdded) {this.excluder = excluder;this.fieldNamingStrategy = fieldNamingStrategy;this.instanceCreators = instanceCreators;this.constructorConstructor = new ConstructorConstructor(instanceCreators);this.serializeNulls = serializeNulls;this.complexMapKeySerialization = complexMapKeySerialization;this.generateNonExecutableJson = generateNonExecutableGson;this.htmlSafe = htmlSafe;this.prettyPrinting = prettyPrinting;this.lenient = lenient;this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;this.longSerializationPolicy = longSerializationPolicy;this.datePattern = datePattern;this.dateStyle = dateStyle;this.timeStyle = timeStyle;this.builderFactories = builderFactories;this.builderHierarchyFactories = builderHierarchyFactories;List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();// built-in type adapters that cannot be overriddenfactories.add(TypeAdapters.JSON_ELEMENT_FACTORY);factories.add(ObjectTypeAdapter.FACTORY);// the excluder must precede all adapters that handle user-defined typesfactories.add(excluder);// users' type adaptersfactories.addAll(factoriesToBeAdded);//添加factory// type adapters for basic platform typesfactories.add(TypeAdapters.STRING_FACTORY);factories.add(TypeAdapters.INTEGER_FACTORY);factories.add(TypeAdapters.BOOLEAN_FACTORY);factories.add(TypeAdapters.BYTE_FACTORY);factories.add(TypeAdapters.SHORT_FACTORY);TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));factories.add(TypeAdapters.newFactory(double.class, Double.class,doubleAdapter(serializeSpecialFloatingPointValues)));factories.add(TypeAdapters.newFactory(float.class, Float.class,floatAdapter(serializeSpecialFloatingPointValues)));factories.add(TypeAdapters.NUMBER_FACTORY);factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);factories.add(TypeAdapters.CHARACTER_FACTORY);factories.add(TypeAdapters.STRING_BUILDER_FACTORY);factories.add(TypeAdapters.STRING_BUFFER_FACTORY);factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));factories.add(TypeAdapters.URL_FACTORY);factories.add(TypeAdapters.URI_FACTORY);factories.add(TypeAdapters.UUID_FACTORY);factories.add(TypeAdapters.CURRENCY_FACTORY);factories.add(TypeAdapters.LOCALE_FACTORY);factories.add(TypeAdapters.INET_ADDRESS_FACTORY);factories.add(TypeAdapters.BIT_SET_FACTORY);factories.add(DateTypeAdapter.FACTORY);factories.add(TypeAdapters.CALENDAR_FACTORY);factories.add(TimeTypeAdapter.FACTORY);factories.add(SqlDateTypeAdapter.FACTORY);factories.add(TypeAdapters.TIMESTAMP_FACTORY);factories.add(ArrayTypeAdapter.FACTORY);factories.add(TypeAdapters.CLASS_FACTORY);// type adapters for composite and user-defined typesfactories.add(new CollectionTypeAdapterFactory(constructorConstructor));factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);factories.add(jsonAdapterFactory);factories.add(TypeAdapters.ENUM_FACTORY);factories.add(new ReflectiveTypeAdapterFactory(constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));this.factories = Collections.unmodifiableList(factories);}

因為我們采用的是new?Gson(),由于我們沒有添加自定義的Adapter,最后只能由ReflectiveTypeAdapterFactory進行處理。

直接看ReflectiveTypeAdapterFactory的create方法

@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {Class<? super T> raw = type.getRawType();//這里用于比對類型,如果不是相應的類型就返回null//確定此* {@code Class}對象表示的類或接口是否與指定的{{code code}}參數所表示的類或接口相同,或者是該類或接口的超類或父接口。 。如果是,則返回{@code true}; *否則返回{@code false}//很顯然,這里返回的是true 應為我們的類是TestMode 是一個class類if (!Object.class.isAssignableFrom(raw)) {return null; // it's a primitive!}//通用對象構造工廠ObjectConstructor<T> constructor = constructorConstructor.get(type);return new Adapter<T>(constructor, getBoundFields(gson, type, raw));}

getBoundFields(gson, type, raw)方法,通過反射獲取類的屬性。

private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();if (raw.isInterface()) {return result;}Type declaredType = type.getType();while (raw != Object.class) {Field[] fields = raw.getDeclaredFields();for (Field field : fields) {boolean serialize = excludeField(field, true);boolean deserialize = excludeField(field, false);if (!serialize && !deserialize) {continue;}accessor.makeAccessible(field);Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());List<String> 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 nameBoundField boundField = createBoundField(context, field, name,TypeToken.get(fieldType), serialize, deserialize);BoundField replaced = result.put(name, boundField);if (previous == null) previous = replaced;}if (previous != null) {throw new IllegalArgumentException(declaredType+ " declares multiple JSON fields named " + previous.name);}}type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));raw = type.getRawType();}return result; }

debug截圖:

?可以看到getBoundFields()方法結果返回的result是應該map對象,里面存著key為我們類屬性名,value為adapterFactory的對象。

了解了getAapter方法,我們接下來分析ReflectiveTypeAdapterFactory的read方法。

@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);if (field == null || !field.deserialized) {in.skipValue();} else {field.read(in, instance);}}} catch (IllegalStateException e) {throw new JsonSyntaxException(e);} catch (IllegalAccessException e) {throw new AssertionError(e);}in.endObject();return instance; }

?

這里的field就是剛剛getBoundFields()中獲取到的,放在map中的一個。

可以看到它調用的是field.read(in, instance);

return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException {Object fieldValue = field.get(value);TypeAdapter t = jsonAdapterPresent ? mapped : new TypeAdapterRuntimeTypeWrapper(context, mapped, fieldType.getType());((TypeAdapter)t).write(writer, fieldValue);}void read(JsonReader reader, Object value) throws IOException, IllegalAccessException {Object fieldValue = mapped.read(reader);if (fieldValue != null || !isPrimitive) {field.set(value, fieldValue);}}

? ?根據debug截圖可以看出,fieldValue是typeAdapter調用read之后解析出來的值,就跟我們現在所跟的流程一樣,因為這里“java書籍“是String所以會到String對應的Adapter中解析,如果是我們自定義類的話還是會走再一遍反射。可以看到value是Book對象,

?都還是null,field對應的是name屬性,所以接下來set方法將fieldValue設置到Book對象的name屬性中。

?可以看到set方法后,book對象的name就有值了。

看下read方法最后返回的就是解析完成的對象,

序列化toJson同樣需要經過反射,

可以看ReflectiveTypeAdapterFactory的write方法,

@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(); }

?它也是調boundField的方法,boundField.write(out, value);

@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); }

?可以看到write之后,out屬性被寫上了“name“:”java書籍“。

?最終結果返回的是writer.toString()。

?

總結

以上是生活随笔為你收集整理的Android—Gson原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。