一、前言
在原生應(yīng)用開發(fā)中,我們通常會使用YYModel
港柜、SwiftyJSON
、GSON
等庫實現(xiàn)JSON
解析,并使用JSONConverter等類似工具實現(xiàn)JSON自動轉(zhuǎn)模型夏醉,極大的提高工作效率爽锥。
但在Flutter
開發(fā)中,卻并沒有類似的解析庫給我們使用畔柔,因為這樣的庫需要使用運行時反射氯夷,這在Flutter
中是禁用的。運行時反射會干擾Dart
的tree shaking
靶擦,使用_tree shaking_
腮考,可以在release
版中“去除”未使用的代碼,這可以顯著優(yōu)化應(yīng)用程序的大小玄捕。由于反射會默認(rèn)應(yīng)用到所有代碼踩蔚,因此_tree shaking_
會很難工作,因為在啟用反射時很難知道哪些代碼未被使用桩盲,因此冗余代碼很難剝離寂纪,所以Flutter
中禁用了Dart
的反射功能席吴,而正因如此也就無法實現(xiàn)動態(tài)轉(zhuǎn)化Model
的功能赌结。
二、json_serializable
雖然不能在Flutter
中使用運行時反射孝冒,但官方提供了類似易于使用的API
柬姚,它是基于代碼生成庫實現(xiàn),json_serializable package庄涡,它是一個自動化的源代碼生成器量承,可以生成JSON
序列化模板,由于序列化代碼無需手寫和維護(hù)穴店,將運行時產(chǎn)生JSON
序列化異常的風(fēng)險降至最低撕捍,使用方法如下:
1. 在項目中添加json_serializable
要包含json_serializable
到我們的項目中,需要一個常規(guī)和兩個開發(fā)依賴項泣洞。簡而言之忧风,開發(fā)依賴項是不包含在我們的應(yīng)用程序源代碼中的依賴項。
通過此鏈接可以查看這些所需依賴項的最新版本 球凰。
在您的項目根文件夾中運行
flutter packages get
(或者在編輯器中點擊 Packages Get
) 以在項目中使用這些新的依賴項.
2. 以json_serializable的方式創(chuàng)建model類
讓我們看看如何將我們的User類轉(zhuǎn)換為一個json_serializable
狮腿。為了簡單起見,我們使用前面示例中的簡化JSON model
呕诉。
- user.dart
import 'package:json_annotation/json_annotation.dart';
// user.g.dart 將在我們運行生成命令后自動生成
part 'user.g.dart';
///這個標(biāo)注是告訴生成器缘厢,這個類是需要生成Model類的
@JsonSerializable()
class User {
String name;
String email;
User(this.name, this.email);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
有了這個設(shè)置,源碼生成器將生成用于序列化name
和email
字段的JSON
代碼甩挫。
如果需要贴硫,自定義命名策略也很容易。例如伊者,如果我們正在使用的API
返回帶有snake_case
的對象英遭,但我們想在我們的模型中使用lowerCamelCase
拖刃, 那么我們可以使用@JsonKey
標(biāo)注:
@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;
3. 運行代碼生成程序
- 一次性生成
通過在我們的項目根目錄下運行flutter packages pub run build_runner build
,我們可以在需要時為我們的Model
生成JSON
序列化代碼贪绘。 這觸發(fā)了一次性構(gòu)建兑牡,它通過我們的源文件,挑選相關(guān)的并為它們生成必要的序列化代碼税灌。
- 持續(xù)生成
雖然這非常方便均函,但如果我們不需要每次在model
類中進(jìn)行更改時都要手動運行構(gòu)建命令的話會更好。
使用watcher
可以使我們的源代碼生成的過程更加方便菱涤。它會監(jiān)視我們項目中文件的變化苞也,并在需要時自動構(gòu)建必要的文件。我們可以通過flutter packages pub run build_runner watch
在項目根目錄下運行來啟動watcher
粘秆。
只需啟動一次觀察器如迟,然后并讓它在后臺運行,這是安全的
4. 使用json_serializable模型
要通過json_serializable
方式反序列化JSON
字符串攻走,我們不需要對先前的代碼進(jìn)行任何更改殷勘。
Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);
序列化也一樣。調(diào)用API
與之前相同昔搂。
String json = JSON.encode(user);
有了json_serializable
玲销,我們只需要編寫User
類文件 。源代碼生成器創(chuàng)建一個名為user.g.dart
的文件摘符,它具有所有必需的序列化邏輯贤斜。 現(xiàn)在,我們不必編寫自動化測試來確保序列化的正常工作 - 這個庫會確保序列化工作正常逛裤。
三瘩绒、 JSONConverter
如上面所寫,即便使用了json_serializable
带族,仍然需要手動編寫模型類文件并逐一編寫對應(yīng)的模型屬性锁荔,生產(chǎn)工作中一個項目可能會有幾百個API
, 如果全部手寫依舊浪費大量摸魚的時間,這里我們可以使用JSONConverter, 它可根據(jù)后臺返回的JSON
自動生成模型文件炉菲,配合json_serializable
堕战,可以非常方便的實現(xiàn)接口對接,模型文件一鍵生成拍霜,極大節(jié)省程序員的體力嘱丢。
另外
JSONConverter
除了支持Flutter
,還支持其他語言和第三方庫祠饺,功能可能說非常豐富了越驻。四、總結(jié)
生產(chǎn)項目中推薦使用json_serializable
+ JSONConverter 完成服務(wù)端返回的JSON
數(shù)據(jù)解析工作,效率翻倍!!
五月幌、參考
[Flutter] 08-Flutter中的Json轉(zhuǎn)Model
Flutter的Json和Model轉(zhuǎn)換
效率翻倍妹窖!大型Flutter項目快速實現(xiàn)JSON轉(zhuǎn)Model實戰(zhàn)