iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
0
Mobile Development

用 Flutter 開發一個 Android App 吧系列 第 19

用 Flutter 開發一個 Android App 吧 - Day 19. JSON 序列化 及 如何應用在 App 中

本系列同步發表在 個人部落格,歡迎大家關注~

好了,經歷了一天 Hacker News API 和四天 GitHub API ,藉著 hnpwa_clientgithub 兩大套件之力,可說是省了不少力。

為何會這麼說呢?因為接下來要進行對接的 GitHub Trending API 是沒有套件輔助的,也就是說我要自己建造輪子拉!

那麼廢話不多說,直接講解吧~

JSON 序列化(JSON serialization)

有寫程式的人應該不陌生,目前 JSON 是主流的資料格式之一,所以幾乎所有語言都有內建或有強大的第三方套件來作 JSON 序列化。

如 Python 的內建 json 函式庫、 Java 的 GSON / Jackson / Moshi 這些第三方套件。

那麼 Dart 有內建的函式庫嗎? 當然是有的,就在 dart:convert 裡;不過呢,因為 dart:convert 只提供簡單的 decode / encode function,所以這邊要介紹另一個套件: json_serializable
這也是 Flutter 官方網站提供的 JSON 序列化解決方案,甚至還有教學文章呢~

那就迅速地將套件加入進 pubspec.yaml

dependencies:
  ...
  
  # JSON Parsing
  json_annotation: ^3.0.0
  
dev_dependencies:
  ...

  # JSON Parsing
  build_runner: ^1.0.0
  json_serializable: ^3.2.0

咦~ 怎麼加入這麼多套件阿?

嘿嘿,稍微講解他們的功用:

  • json_serializable: JSON 序列化的主體,提供主要的轉換功能,讓你可以自由的從 JSON 字串轉換成自定義的物件。
  • json_annotation: JSON 序列化的輔助之一,定義 JSON key-value 和物件屬性間的對應轉換,看到 @ 這個符號開頭就是照套件提供的函數。
  • build_runner: JSON 序列化的輔助之一,自動生成程式碼的工具,第一點說到 json_serializable 提供主要的轉換功能,是需要透過此套件來自動生成函數,後面會進一步接觸到。

看到講解後是不是有種好複雜的感覺...
沒錯,當然這套件也因此而強大喔~

小提醒:

  • json_serializable 其實有很多的依賴套件,見下圖紅框。
    day19-1.png
    還滿多是有關自動生成程式的套件。
  • 自動生成(Source-code generation)的技術似乎是最近滿流行的寫法,不過本系列還是著重於實作部份,技術深入探討以後有空再做補充吧~

自定義物件模板

在 JSON 序列化過程中,第一步就是要定義物件模板(Object Model),
而在 App 對接 Web API 中,通常只需要定義回應 (Response) 的物件模板。

直接看實例

day19-2.png

  • 上半部紅框是函數引用(import)
    1. import "package:json_annotation/json_annotation.dart"; 是引用自json_annotation
    2. part "project.g.dart"; 是自動生成程式後需要引入的檔案名稱,其中的 .g. 是指 generation 的意思
  • 下半部紅框是自定義的物件模板類別
    1. @JsonSerializablejson_annotation 提供的裝飾子,用來標記這類別為 JSON 序列化的物件模板。
    2. Project 這類別是最重要的部份,裡頭的屬性對應 Response 的 key,參考下圖
      day19-3.png
    3. Project.fromJsontoJson 為 JSON 與物件之間轉換的方法,有點類似 decode 和 encode 的感覺。
    4. _$ 開頭的函數是自動生成的,後續會談到。

自動生成的 JSON 轉換函數

自動生成的方式很簡單,在 Terminal 中打入 flutter pub run build_runner build 就可以了

$ flutter pub run build_runner build
[INFO] Generating build script...
[INFO] Generating build script completed, took 262ms

[INFO] Creating build script snapshot......
[INFO] Creating build script snapshot... completed, took 11.0s

[INFO] Initializing inputs
[INFO] Building new asset graph...
[INFO] Building new asset graph completed, took 708ms

[INFO] Checking for unexpected pre-existing outputs....
[INFO] Checking for unexpected pre-existing outputs. completed, took 1ms

[INFO] Running build...
[INFO] 1.1s elapsed, 0/16 actions completed.
[INFO] 2.1s elapsed, 0/16 actions completed.
[INFO] 3.2s elapsed, 0/16 actions completed.
[INFO] 4.2s elapsed, 0/16 actions completed.
[INFO] 5.3s elapsed, 0/16 actions completed.
[INFO] 10.0s elapsed, 1/16 actions completed.
[INFO] 11.1s elapsed, 17/28 actions completed.
[INFO] Running build completed, took 11.3s

[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 76ms

[INFO] Succeeded after 11.4s with 2 outputs (57 actions)

看到 Succeeded 字眼後就能在 lib/services/models/project.dart 同層資料夾中找到自動產生的 project.g.dart,而裡頭就會看到上一小節提到的 _$ 開頭的函數: _$ProjectFromJson_$ProjectToJson

day19-4.png

lib/services/models/project.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'project.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

...

project.g.dart 最上面,可以看到這段,很明顯是自動生成的程式,而且還標明不要自行修改~

自定義物件模板 - Developer

原則上 Developer 撰寫的方法跟 Project 概念是一樣的。

這邊就直接貼上 Commit 圖片

day19-5.jpeg

參考

--

插曲 - 一切都是美麗的錯誤

因為新組了一台電腦,昨天都在處理它,結果準備好的文章就忘記發了...

哭阿~~ !! /images/emoticon/emoticon02.gif

哀,看來無緣拿獎了,總之 30 天還是會慢慢發完吧...


上一篇
用 Flutter 開發一個 Android App 吧 - Day 18. 個人頁面(大改)
下一篇
用 Flutter 開發一個 Android App 吧 - Day 20. 自己建造 GitHub Trending API 輪子與測試
系列文
用 Flutter 開發一個 Android App 吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言