【Android】【框架】【JSON】【Gson】

整體架構

image.png

核心在于TypeAdapter,它定義了類型和字節(jié)之間的相互轉(zhuǎn)換

TypeAdapter

image.png
image.png
public abstract class TypeAdapter<T> {

  public abstract void write(JsonWriter out, T value) throws IOException;

  public abstract T read(JsonReader in) throws IOException;

  ...
}

看Json代碼示例

{
            "test1": "wx9fdb8ble7ce3c68f",
            "test2": 123456789,
            "testData1": {   
                "testdatason1": "97895455"
                "testdatason2":3,
             }
}

解析Json睬澡,當解析到value的時候固额,會去獲取對應的TypeAdapter,具體是到一個List<TypeAdapter>按序匹配煞聪,如果沒有名字斗躏,采用反射

image.png
  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) {
    ...
    ...
    ...

    List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();

    // built-in type adapters that cannot be overridden
    factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
    factories.add(ObjectTypeAdapter.FACTORY);

    // the excluder must precede all adapters that handle user-defined types
    factories.add(excluder);

    // users type adapters
    factories.addAll(factoriesToBeAdded);

    // type adapters for basic platform types
    factories.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 types
    factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
    factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
    this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
    factories.add(jsonAdapterFactory);
    factories.add(TypeAdapters.ENUM_FACTORY);
    // 注意,ReflectiveTypeAdapterFactor是要最后添加的
    factories.add(new ReflectiveTypeAdapterFactory(
        constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));

    this.factories = Collections.unmodifiableList(factories);
  }

對于自定義對象其實就是通過ReflectiveTypeAdapterFactory來做的
內(nèi)部其實還是調(diào)用的基本數(shù)據(jù)類型TypeAdapter

總結

1米绕、整體分為2部分瑟捣,一個是TypeAdapter,定義寫入寫出栅干;一個是容器,用于存放JSON
2捐祠、對于自定義對象解析碱鳞,需要反射獲取對象字段,然后挑選具體的TypeAdapter
3踱蛀、對于自定義對象循環(huán)嵌套的情況窿给,使用FutureTypeAdapter,單個對象只需解析一次
4率拒、對于多線程情況崩泡,用ThreadLocal支持

后記

有什么寫得錯誤、讓人費解或遺漏的地方猬膨,希望可以不吝賜教角撞,我會馬上更改

學習自

https://mp.weixin.qq.com/s/j-klYVIjJxeWWIGfdeBsEw
https://blog.csdn.net/chunqiuwei/article/details/49401733

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市勃痴,隨后出現(xiàn)的幾起案子谒所,更是在濱河造成了極大的恐慌,老刑警劉巖沛申,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劣领,死亡現(xiàn)場離奇詭異,居然都是意外死亡铁材,警方通過查閱死者的電腦和手機尖淘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來著觉,“玉大人村生,你說我怎么就攤上這事」坦撸” “怎么了梆造?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我镇辉,道長屡穗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任忽肛,我火速辦了婚禮村砂,結果婚禮上,老公的妹妹穿的比我還像新娘屹逛。我一直安慰自己础废,他們只是感情好,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布罕模。 她就那樣靜靜地躺著评腺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淑掌。 梳的紋絲不亂的頭發(fā)上蒿讥,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音抛腕,去河邊找鬼芋绸。 笑死,一個胖子當著我的面吹牛担敌,可吹牛的內(nèi)容都是我干的虹钮。 我是一名探鬼主播钓葫,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼秦士,長吁一口氣:“原來是場噩夢啊……” “哼榄檬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起售貌,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤给猾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后颂跨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敢伸,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年恒削,在試婚紗的時候發(fā)現(xiàn)自己被綠了池颈。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡钓丰,死狀恐怖躯砰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情携丁,我是刑警寧澤琢歇,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布兰怠,位于F島的核電站,受9級特大地震影響李茫,放射性物質(zhì)發(fā)生泄漏揭保。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一魄宏、第九天 我趴在偏房一處隱蔽的房頂上張望秸侣。 院中可真熱鬧,春花似錦宠互、人聲如沸味榛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搏色。三九已至,卻和暖如春券册,著一層夾襖步出監(jiān)牢的瞬間继榆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工汁掠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人集币。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓考阱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鞠苟。 傳聞我的和親對象是個殘疾皇子乞榨,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容