只要咱們的app不是單機的,那麼必然涉及到遠程服務器數據請求。在flutter
中,發起請求已經有現成的包dio
了,使用起來也很是簡練方便,如仍是不是很瞭解,能夠點擊查看dio的詳細文檔。javascript
發起請求,拿到服務端返回的json數據後,接下來的步驟是怎麼樣的。flutter
(應該說是Dart
)可不像javascript
那樣,對json
天生友好。這就是本文要講的主要內容。你將會學到:html
flutter
項目json
數據處理的詳細步驟和踩坑提醒json_serializable
環節,命令行+工具,幫你自動化生成相關代碼,無需手敲,無需手敲(重要的事情說兩遍)請求回來數據後,下一步必然就是讀取其中的數據信息,而後依此進行界面展現和邏輯處理了。java
若是返回來的是簡單的數據,並且業務邏輯也很簡單,那麼其實處理方式也能夠簡單化,例如服務端返回數據以下:git
{
code: 200,
message: null,
value: true
}
複製代碼
那麼,你甚至能夠這麼處理:github
if (jsonStr.indexOf('true') != -1) {
// do something
}
複製代碼
總結的說,在這種場景下面,使用正則表達式匹配或者簡單字符串處理邏輯,進行簡單快速的實現,也不失爲一種好方法。正則表達式
可是,當數據結構足夠複雜(例如:點擊查看複雜數據示例),那麼上述的方式顯然就有點捉襟見肘了。shell
這個時候,就該輪到本文要講述的重點,json
反序列化上場了。關於序列化和反序列化,能夠上網查一下,有不少資料(實在不想查,好吧,這裏有現成的,點擊序列化湊合着看一下吧...)。json
在本文描述的業務場景下面,也能夠簡單理解爲,咱們要作的,就是把經過dio
拿到的服務端json
字符串數據,轉換爲對象,而後就能夠愉快的訪問該對象中的字段值了。api
主要的步驟有兩個:bash
json
字符串轉換爲Map
對象json_serializable
進行反序列化具體步驟以下:
參考下面代碼,往pubspec.yaml
文件中添加json_annotation
、json_serializable
和build_runner
包。
dependencies:
flutter:
sdk: flutter
json_annotation: ^3.0.0
dev_dependencies:
flutter_test:
sdk: flutter
json_serializable: ^3.2.0
build_runner: ^1.6.5
複製代碼
添加完,記得flutter packages get
xxxx.dart
(文件一,會在下文的代碼中引用到)copy到項目中若是你已經看過其餘相關文章,頗有多是要你根據json
數據寫一個dart的實體類,其實,也能夠的,選擇你喜歡方式就好了。本文推薦工具生成,方便快捷,不易出錯,哈哈。。。
若是,你還沒來得及準備好試驗的json
數據,點擊本文爲你提供的數據示例,copy到工具中,愉快的玩耍吧。
flutter packages pub run build_runner build
,命令執行完成,根據剛剛的xxxx.dart
生成xxxx.g.dart
(該文件生成後不要手動改,也無需引用,放着不動就是了)import 'dart:convert';
import 'package:xxxxxxx/xxxx.dart'; //引入上面說起的文件一
String jsonStr = '{"value":1}'; //你要進行反序列化的json字符串
Map<String ,dynamic> map = json.decode(jsonStr); //先轉成Map
MyObject obj = MyObject.fromJson(map); //假設class名爲MyObject,這個根據實際狀況調整
print(obj.value);
複製代碼
到此,基本就完成了數據的反序列化。上述代碼中,主要是兩個步驟:
MyObject
即引入的「文件一」中的類名,可根據實際狀況進行調整。
也可能你會有疑問,既然原生已經提供了String to Map
,那麼只作到這一步,而後使用map對象進行接下來的coding,ok嗎。
其實,也是能夠的,只是。。。,下面舉個列子對比一下,便一目瞭然了。以該數據示例爲例,下面兩行代碼,訪問的字段是同樣的:
print(homePageList.value[0].modules[0].items[1].title);
print(map.entries.elementAt(2).value[0].entries.elementAt(5).value[0].entries.elementAt(11).value[1].entries.elementAt(0).value);
複製代碼
不知你喜歡哪一種方式呢。。。
按照上述的具體步驟,基本能夠處理大部分的規則數據了,可是當你以數據示例爲數據源,一步一步操做coding完,訪問其中某些字段的值時,意想不到的事情發生了:
print(homePageList.value[0].modules[0].items[1].title); //正常打印
print(homePageList.value[0].modules[2].items[0].name); // 報錯
複製代碼
報錯信息:
The following NoSuchMethodError was throw building BlockRowFrame(dirty):
Class 'Modules' has no instance getter 'title'.
...
複製代碼
這是由於,數據每一項的結構不一致致使的。數據示例中,字段name
在前兩個modules
的items
元素中並無,而在第三個modules
的items
元素中,卻有了。
遇到這種狀況,只須要在用工具生成的"文件一"中對應的class
,手動添加上對應的字段代碼,而後再從新運行一次flutter packages pub run build_runner build --delete-conflicting-outputs
即可。
到此,關於flutter json
數據處理分享就講完了。碼字不易,以爲此文對你有幫助的,麻煩點個贊鼓勵鼓勵。
若是還有不清楚的地方。。。
不要緊,源碼伺候,點擊flutter_examples訪問對應的github項目,其中的「json格式請求結果反序列化與使用(dio & json_serializable demo)」實例,就是本文的代碼實現!