Flutter JSON和序列化

此文注重梳理官方文檔和整合實(shí)際開發(fā)的業(yè)務(wù)場景進(jìn)行分析呕乎,鞏固基礎(chǔ)荚斯。

首先,F(xiàn)lutter中是否有GSON / Jackson / Moshi霉颠?官方文檔明確表明--沒有对碌!且是禁用的,因?yàn)檫@些工具使用了反射機(jī)制蒿偎,反射會默認(rèn)使用Dark所有代碼俭缓,讓tree shaking會很難工作,運(yùn)用文檔所說的:\color{#FF0000}{這些工具無法知道哪些widget在運(yùn)行時未被使用酥郭,因此冗余代碼很難剝離。使用反射時愿吹,應(yīng)用尺寸無法輕松的進(jìn)行優(yōu)化不从。}

使用 dart:convert手動序列化JSON

使用工具:Flutter有一個內(nèi)置dart:convert庫
關(guān)鍵代碼:

  • User.fromJson 構(gòu)造函數(shù), 用于從一個map構(gòu)造出一個 User實(shí)例 map structure
  • toJson 方法, 將 User 實(shí)例轉(zhuǎn)化為一個map.

解析代碼:

import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';

class User {
  final String name;
  final String password;

  User(this.name, this.password);

  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        password = json['password'];

  Map<String, dynamic> toJson() => {
        'name': name,
        'password': password,
      };
}

String jsonStr = "{\"name\": \"Hank\",\"password\": \"123456\"}";//解析數(shù)據(jù)

void main() {
  test('json test', () {
    Map userMap = json.decode(jsonStr);
    var user = new User.fromJson(userMap);

    print('name, ${user.name}!');
    print('password, ${user.password}.');
    print('user json, ${user.toJson()}.');
  });
}

運(yùn)行以上代碼時請務(wù)必注意該圖標(biāo)標(biāo)志方可運(yùn)行,否則報錯犁跪。

運(yùn)行結(jié)果

使用代碼生成庫序列化JSON

使用了json_serializable package包椿息,它是一個自動化的源代碼生成器。

pubspec.yaml

dependencies:
  # Your other regular dependencies here
  json_annotation: ^2.0.0

dev_dependencies:
  # Your other dev_dependencies here
  build_runner: ^1.0.0
  json_serializable: ^2.0.0

注意坷衍,yaml配置文件對于縮進(jìn)要求十分嚴(yán)格寝优,下面的build_runner和json_serializable應(yīng)該
是dev_dependencies的一級子項(xiàng),json_serializable千萬不要寫在build_runner縮進(jìn)后枫耳,這樣它會認(rèn)為是build_runner的子集目錄乏矾!
在項(xiàng)目根文件夾中運(yùn)行 flutter packages get (或者在編輯器中點(diǎn)擊 “Packages Get”) 以在項(xiàng)目中使用這些新的依賴項(xiàng)。

解析代碼:

import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:json_annotation/json_annotation.dart';

// user.g.dart 將在我們運(yùn)行生成命令后自動生成
part 'user.g.dart';

@JsonSerializable()
class User {
  String name;
  String password;

  User(this.name, this.password);

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);
}

String jsonStr = "{\"name\": \"Hank\",\"password\": \"123456\"}";

void main() {
  test('json test', () {
    Map userMap = json.decode(jsonStr);
    var user = new User.fromJson(userMap);

    print('name, ${user.name}!');
    print('password, ${user.password}.');
    print('user json, ${user.toJson()}.');
  });
}

復(fù)制以上代碼使用json_serializable第一次創(chuàng)建類時迁杨,您會看到與下圖類似的錯誤钻心。



這些錯誤是完全正常的,這是因?yàn)閙odel類的生成代碼還不存在铅协。為了解決這個問題捷沸,我們必須運(yùn)行代碼生成器來為我們生成序列化模板。這就讓我想起和Dagger一樣需要預(yù)編譯才可以調(diào)用生成類狐史。

有兩種運(yùn)行代碼生成器的方法:

一次性生成

通過在我們的項(xiàng)目根目錄下運(yùn)行flutter packages pub run build_runner build痒给,我們可以在需要時為我們的model生成json序列化代碼。 這觸發(fā)了一次性構(gòu)建骏全,它通過我們的源文件苍柏,挑選相關(guān)的并為它們生成必要的序列化代碼。
雖然這非常方便姜贡,但如果我們不需要每次在model類中進(jìn)行更改時都要手動運(yùn)行構(gòu)建命令的話會更好序仙。

持續(xù)生成

使用watcher可以使我們的源代碼生成的過程更加方便。它會監(jiān)視我們項(xiàng)目中文件的變化鲁豪,并在需要時自動構(gòu)建必要的文件潘悼。我們可以通過flutter packages pub run build_runner watch在項(xiàng)目根目錄下運(yùn)行來啟動watcher律秃。
只需啟動一次觀察器,然后并讓它在后臺運(yùn)行治唤,這是安全的棒动。

但是如果你運(yùn)行了以上命令行均沒有生成user.g.dart那可能你沒有做到以下規(guī)范:

dart代碼中User首字母可以大寫,但是文件名字建議全部為小寫,如user.dart,與User類名同名宾添,生成代碼的時候會匹配文件名和類名是否一致船惨,否則無法生成user.g.dart。
當(dāng)然如果已經(jīng)有User類名能匹配到文件名后缕陕,在該文件再編寫其他不同名的@JsonSerializable class也是能正常編譯出來粱锐。

@JsonKey標(biāo)注:
如果我們正在使用的API返回帶有registration_date_millis字段,但我們想在我們的模型中使用registrationDateMillis

@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扛邑,一起剝皮案震驚了整個濱河市怜浅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔬崩,老刑警劉巖恶座,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沥阳,居然都是意外死亡跨琳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門桐罕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脉让,“玉大人,你說我怎么就攤上這事功炮∠丽” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵死宣,是天一觀的道長伟恶。 經(jīng)常有香客問我,道長毅该,這世上最難降的妖魔是什么博秫? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮眶掌,結(jié)果婚禮上挡育,老公的妹妹穿的比我還像新娘。我一直安慰自己朴爬,他們只是感情好即寒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般母赵。 火紅的嫁衣襯著肌膚如雪逸爵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天凹嘲,我揣著相機(jī)與錄音师倔,去河邊找鬼。 笑死周蹭,一個胖子當(dāng)著我的面吹牛趋艘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凶朗,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼瓷胧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了棚愤?” 一聲冷哼從身側(cè)響起搓萧,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遇八,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耍休,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刃永,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了羊精。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斯够。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喧锦,靈堂內(nèi)的尸體忽然破棺而出读规,到底是詐尸還是另有隱情,我是刑警寧澤燃少,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布束亏,位于F島的核電站,受9級特大地震影響阵具,放射性物質(zhì)發(fā)生泄漏碍遍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一阳液、第九天 我趴在偏房一處隱蔽的房頂上張望怕敬。 院中可真熱鬧,春花似錦帘皿、人聲如沸东跪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虽填。三九已至丁恭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卤唉,已是汗流浹背涩惑。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桑驱,地道東北人竭恬。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像熬的,于是被迫代替她去往敵國和親痊硕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

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

  • 在 Flutter 中使用JSON 現(xiàn)在網(wǎng)上已經(jīng)有很多教程了押框。此篇文章用于記錄和學(xué)習(xí)使用參考 Flutter中文網(wǎng)...
    zda123000閱讀 4,431評論 0 9
  • 前言 Google推出flutter這樣一個新的高性能跨平臺(Android岔绸,ios)快速開發(fā)框架之后,被業(yè)界許多...
    Vadaski閱讀 32,050評論 15 42
  • 不同的項(xiàng)目具有不同的復(fù)雜度和場景橡伞。對于較小項(xiàng)目盒揉,使用代碼生成器可能會過度。對于具有多個JSON model的復(fù)雜應(yīng)...
    小哥_xiaoge閱讀 11,305評論 2 3
  • Flutter開發(fā)過程中兑徘,經(jīng)常需要進(jìn)行對象進(jìn)行JSON序列化刚盈,進(jìn)行網(wǎng)絡(luò)交互。由于Flutter中禁止使用反射挂脑,影響...
    海_3efc閱讀 2,005評論 0 2
  • Flutter中的JSON和序列化 前言:本篇文章適合已經(jīng)了解Dart基礎(chǔ)語法的情況下閱讀藕漱,若你對于Dart的一些...
    EasonZzz閱讀 1,663評論 1 7