導入 Flutter 前
你應該知道的事
Weizhong Yang a.k.a zonble

zonble@gmail.com
關於我
• 在 KKBOX ⼯作的⼯程師

• 主要從事蘋果平台開發

• 做過 KKBOX iOS、macOS、tvOS 版本,以及 KKTIX、
Uta Pass 等產品,最近⽤ Flutter 做了 KKBOX Kids

• GDE for Flutter
我們的經驗
• 從 2018 年 Google I/O 之後開始接觸

• 2018 年八⽉開始⽤ Flutter 做⼀些 Side
Project

• iPlayground 研討會 App

• ⼀些不太能夠公開的內部 POC…

• 2018 年底嘗試⽤ Flutter 做 KKBOX 風雲榜
App

• 2019 年五⽉推出 KKBOX Kids
今天的主題
• 什麼是 Flutter?Flutter 如何加速產品開發?

• 你是否應該導入 Flutter?

• 新⼿怎樣學 Flutter?

• 你可能會遇到的疑難雜症

• Flutter 的軟體⼯程
什麼是 Flutter?
什麼是 Flutter
• 把瀏覽器的元件打散後重組,打造⼀個逼近 Native 速度的
應⽤程式開發環境

• 瀏覽器:發送 HTTP 連線、抓取 HTML(CSS、JS)、把
HTML Parse 成 DOM、⽤ JavaScript 操作 DOM,⽤
Render 繪製畫⾯

• Flutter:AOT 編譯,直接組好 Widget Tree,⽤ Dart 語⾔
操作 Widgets,Widget 同時包含元件與樣式,沒有另外拆
分 CSS
什麼是 Flutter
• 在 iOS 上有⼀個 FlutterViewController、在 Android 上有⼀
個 Flutter Activity,當中包含 Dart VM 與 Skia Render
Engine

• 沒有⽤到 UIKit 或是 Android UI Components,⽽是⽤⾃⼰
的引擎繪製元件

• 在不同平台上可以繪製出完全相同的 UI

• 預設提供 Material 與 Cupertino 兩套 Widget
Flutter 如何加速開發?
• 規劃新產品時,⽬前的趨勢是雙平台同時開發

• 不同平台之間往往存在若⼲差異,同⼀套設計,在不同平
台上可能各⾃有開發上困難的地⽅

• 產品討論的時間不會少於實際開發的時間

• Flutter 可以在不同平台使⽤同⼀套 UI 設計與 UI
codebase,省下討論的時間,直接進入產品開發
與 HTML 跨平台框架比較
• PhoneGap/Cordova

• Flutter Engine 效能明顯優於 Web View

• 執⾏編譯過的 Dart 程式,毋需在 runtime 解析

• 與 JS 相比,Dart 很少有出乎意料的⾏為

• Dart/Flutter 的 Pattern 也較眾多 HTML/JS 開發框架單⼀
與 NativeScript/RN比較
• RN 等框架標榜 Learn once, write everywhere。但是
Flutter 可以同⼀套程式在 iOS/Android 等平台執⾏

• 執⾏編譯過的 Dart 程式,毋需在 runtime 解析
你是否應該導入
Flutter?
怎樣的 App 適合 Flutter?
• 原本是網站功能,但是要做成 Mobile App 的最適合

• 電商、售票、交友、報表…

• 如果要做遊戲,還是建議使⽤遊戲引擎

• 如果要做更接近硬體功能的 App,像是拍照、錄影…還是
建議使⽤ Native 開發框架
導入之前
• 先確定你已經有完整的⼈才

• 先掌握新技術之後,再導入到實際的產品中

• 先從比較⼩的專案開始,再導入到比較⼤的專案
最後…你還是在做 iOS/Android
App
• 除了 Flutter 之外…

• Cocoa Pods/Gradle 套件管理

• Android Manifest/ProGuard

• App Code Signing

• CI/CD

• 上架流程
KKBOX Kids 的組成
• UI 使⽤ Flutter 製作

• 呼叫原⽣ Web View 實作 OAuth 登入

• 開發原⽣的⾳樂播放器

• ⾃⼰寫了 Facebook App Events 的 plugin
Flutter 團隊的組成
• ⽬前⼈⼒市場上還比較沒有所謂的 Flutter ⼯程師

• Flutter 簡化了很多⼀般性質的 Mobile App 開發

• 但是 Flutter 不能完全取代所有的 iOS/Android 開發⼯作

• 因此,剩下來的平台相關問題,往往是特別困難的問題

• 在團隊中,還是得要有資深的 iOS/Android ⼯程師

• 建議先學會 iOS/Android 其中⼀種,再來學 Flutter
怎樣學 Flutter
怎樣學 Flutter
• 建置環境,安裝 IDE 與 SDK

• 學習 Dart 程式語⾔與慣例

• 先動⼿寫⼀個 Flutter App 上⼿

• 熟悉 Flutter Widget

• 熟悉 Flutter 的重要 Pattern 與更新機制

• 練習寫 Dart Package

• 練習寫 Flutter Plugin
安裝 IDE 與 SDK
• IDE

• Android Studio

• IntelliJ IDEA

• Visual Studio Code

• Flutter SDK https://flutter.dev/docs/get-started/install

• Dart SDK https://dart.dev/get-dart
學習 Dart 語⾔
• Learn X in Y minutes https://learnxinyminutes.com/docs/
dart/

• Dart Pad https://dartpad.dartlang.org

• Exercism https://exercism.io

• Effective Dart https://dart.dev/guides/language/effective-
dart
動⼿寫第⼀個 Flutter
• Flutter 的 New Project 就已經是⼀個簡單會動的程式了

• 官網教學 https://flutter.dev/docs/get-started/codelab

• 《Flutter 實戰》第⼆章 https://book.flutterchina.club/
chapter2/
Flutter Widgets
• Flutter 的 Widget 的數量非常多,考驗記憶⼒

• https://flutter.dev/docs/reference/widgets

• https://flutter.dev/docs/development/ui/widgets

• https://api.flutter.dev/flutter/widgets/widgets-library.html

• 《實戰 Flutter》三~⼗章
Flutter 的基本 Widget
• Text、Image、Scaffold

• Column、Row、Stack、List、Stack

• Custom ScrollView

• Container、Sized、Expanded、Flexible

• Stream Builder、Future Builder
Flutter 的 Pattern
• 先把你過去學過的 Mobile
開發忘了:MVC、
Singleton、Delegation…

• 即使是 Dart 程式,與
Flutter 程式的典範不太⼀樣

• 在 Flutter 的應⽤程式中,
所有物件都在⼀顆樹裡頭
Pattern?
• Pattern 就是物件之間的關係

• 不該有關係的就不要有關係

• Facade:某個 Class 包含了多個⼦系統,其他⼈都經過這個
介⾯,避免外部與⼦系統發⽣關係

• Singleton:某個 Class 只有⼀個 instance,其他⼈都 access
這個 instance 的多對⼀關係

• Delegate:某個 Class ⾃⼰不做事,交給另外⼀個物件的⼀對
⼀關係
Flutter Pattern
• Flutter 當中 Widget 只有三種關係:

• 另⼀個 Widget 在當前的 Widget 上⽅

• 另⼀個 Widget 在當前的 Widget 下⽅

• 另⼀個 Widget 在當前 Widget 之外的另⼀顆樹裡頭

• 由上層節點決定下層節點的狀態
往上尋找節點
• “of”

• 往上尋找最接近且符合某個型態的節點

• Navigator.of(context).push(route)

• Theme.of(context).primaryColor

• MediaQuery.of(context).padding
往下控制節點
• ⽬前 Widget 的 build method 會產⽣下⽅的 Widget

• 已經建立好了 Widget,想要知道內部的狀態,需要在建立
Widget 時 inject ⼀把 Key 進去

• 已經建立好了 Widget,想要改變下⽅ Widget 的狀態,除
了可以整個重 build,某些 Widget 也提供 controller
另⼀個 Widget
在另⼀顆樹裡頭
• 先往上,再往下

• ⽤ “of” 尋找同時位在這兩個 Widget 共同上⽅的 Widget

• 由這個上⽅的 Widget 往下更新

• 越重要的資料(如登入狀態),放在越上⽅
狀態管理
• UI = f(State)

• Provider

• Bloc (Business Logic Component)
Dart Package 與
Flutter Plugin 開發
• stagehand

• dart pub 發佈
疑難雜症
Android X
• Android 上使⽤ Gradle 管理 plugin 中的 native 部分

• 有些 plugin ⽤了 Android X,有些還在⽤ Android Support
Library,然後就編不起來…

• 發信請作者更新 plugin,或是⾃⼰ fork
iOS 的 OpenGL
• Flutter 在 iOS 上使⽤ OpenGL 繪製 UI

• iOS 不會在背景更新 OpenGL 畫⾯,但是你的 App 可能會
在背景執⾏

• 如果你的 App 可能會在背景,就要在 native code 中保存狀
態,然後在 app 回到前景時更新 Flutter 畫⾯

• 混⽤ OpenGL 的 View,如 MapView,有時也會有靈異現象

• OpenGL 可能在⼀些很詭異的狀況下 Crash
某些 plugin 跟你預期的⾏為不同
• 有些 plugin 做了跟你預期不同的事情

• Local Notification plugin 與 Firebase Messaging plugin 打
架,某些訊息繪被 Local Notification plugin 攔走

• iOS 的 AppDelegate 事件不⼀定會交給哪個 plugin 處理

• 在 iOS 上,有時候要動⽤ Method Swizzling…
Flutter 的軟體⼯程
Flutter 的測試
• Dart 元件的單元測試

• Flutter Widget 的 Widget 測試

• 都有整合進 IDE 中

• 提供 Mockito 協助 Mock 資料
Widget Test
• 所有的 native plugin 都得 mock 掉

• Flutter Widget test 單獨跑在 Dart VM 上,不提供 plugin
所需要的平台功能

• method channel 除了提供 setMethodCallHandler,也提供
setMockMethodCallHandler
CI/CD
• BitRise 對 Flutter ⽀援非常好

• GitHub Actions/Travis 也適合⽤在 Dart Package 的 CI

• 我們在內部使⽤ GitLab CI/Jenkins

• Android 使⽤ Docker Image 編譯

• iOS 使⽤ Mac Mini 編譯
Flutter 與 Native
• Flutter 也可以透過 Plugin呼叫 iOS/Android 的 Native
Code

• Flutter -> Native:Method Channel

• Native -> Flutter:Event Channel

• 將 Native 畫⾯蓋在 Flutter 上:Platform View
Recap
• 什麼是 Flutter?Flutter 如何加速產品開發?

• 你是否應該導入 Flutter?

• 新⼿怎樣學 Flutter?

• 你可能會遇到的疑難雜症

• Flutter 的軟體⼯程
學習資源
• Flutter 官網 https://flutter.dev/

• Flutter 中⽂網 https://flutterchina.club/

• Flutter 官⽅ YouTube 頻道https://www.youtube.com/
channel/UCwXdFgeE9KYzlDdR7TG9cMw

• ⼀堆 Twitter 帳號
KKBOX OpenAPI SDK for
Dart
https://pub.dev/packages/kkbox_openapi

導入 Flutter 前你應該知道的事

  • 1.
    導入 Flutter 前 你應該知道的事 WeizhongYang a.k.a zonble zonble@gmail.com
  • 2.
    關於我 • 在 KKBOX⼯作的⼯程師 • 主要從事蘋果平台開發 • 做過 KKBOX iOS、macOS、tvOS 版本,以及 KKTIX、 Uta Pass 等產品,最近⽤ Flutter 做了 KKBOX Kids • GDE for Flutter
  • 3.
    我們的經驗 • 從 2018年 Google I/O 之後開始接觸 • 2018 年八⽉開始⽤ Flutter 做⼀些 Side Project • iPlayground 研討會 App • ⼀些不太能夠公開的內部 POC… • 2018 年底嘗試⽤ Flutter 做 KKBOX 風雲榜 App • 2019 年五⽉推出 KKBOX Kids
  • 4.
    今天的主題 • 什麼是 Flutter?Flutter如何加速產品開發? • 你是否應該導入 Flutter? • 新⼿怎樣學 Flutter? • 你可能會遇到的疑難雜症 • Flutter 的軟體⼯程
  • 5.
  • 6.
    什麼是 Flutter • 把瀏覽器的元件打散後重組,打造⼀個逼近Native 速度的 應⽤程式開發環境 • 瀏覽器:發送 HTTP 連線、抓取 HTML(CSS、JS)、把 HTML Parse 成 DOM、⽤ JavaScript 操作 DOM,⽤ Render 繪製畫⾯ • Flutter:AOT 編譯,直接組好 Widget Tree,⽤ Dart 語⾔ 操作 Widgets,Widget 同時包含元件與樣式,沒有另外拆 分 CSS
  • 7.
    什麼是 Flutter • 在iOS 上有⼀個 FlutterViewController、在 Android 上有⼀ 個 Flutter Activity,當中包含 Dart VM 與 Skia Render Engine • 沒有⽤到 UIKit 或是 Android UI Components,⽽是⽤⾃⼰ 的引擎繪製元件 • 在不同平台上可以繪製出完全相同的 UI • 預設提供 Material 與 Cupertino 兩套 Widget
  • 8.
    Flutter 如何加速開發? • 規劃新產品時,⽬前的趨勢是雙平台同時開發 •不同平台之間往往存在若⼲差異,同⼀套設計,在不同平 台上可能各⾃有開發上困難的地⽅ • 產品討論的時間不會少於實際開發的時間 • Flutter 可以在不同平台使⽤同⼀套 UI 設計與 UI codebase,省下討論的時間,直接進入產品開發
  • 9.
    與 HTML 跨平台框架比較 •PhoneGap/Cordova • Flutter Engine 效能明顯優於 Web View • 執⾏編譯過的 Dart 程式,毋需在 runtime 解析 • 與 JS 相比,Dart 很少有出乎意料的⾏為 • Dart/Flutter 的 Pattern 也較眾多 HTML/JS 開發框架單⼀
  • 10.
    與 NativeScript/RN比較 • RN等框架標榜 Learn once, write everywhere。但是 Flutter 可以同⼀套程式在 iOS/Android 等平台執⾏ • 執⾏編譯過的 Dart 程式,毋需在 runtime 解析
  • 11.
  • 12.
    怎樣的 App 適合Flutter? • 原本是網站功能,但是要做成 Mobile App 的最適合 • 電商、售票、交友、報表… • 如果要做遊戲,還是建議使⽤遊戲引擎 • 如果要做更接近硬體功能的 App,像是拍照、錄影…還是 建議使⽤ Native 開發框架
  • 13.
  • 14.
    最後…你還是在做 iOS/Android App • 除了Flutter 之外… • Cocoa Pods/Gradle 套件管理 • Android Manifest/ProGuard • App Code Signing • CI/CD • 上架流程
  • 15.
    KKBOX Kids 的組成 •UI 使⽤ Flutter 製作 • 呼叫原⽣ Web View 實作 OAuth 登入 • 開發原⽣的⾳樂播放器 • ⾃⼰寫了 Facebook App Events 的 plugin
  • 16.
    Flutter 團隊的組成 • ⽬前⼈⼒市場上還比較沒有所謂的Flutter ⼯程師 • Flutter 簡化了很多⼀般性質的 Mobile App 開發 • 但是 Flutter 不能完全取代所有的 iOS/Android 開發⼯作 • 因此,剩下來的平台相關問題,往往是特別困難的問題 • 在團隊中,還是得要有資深的 iOS/Android ⼯程師 • 建議先學會 iOS/Android 其中⼀種,再來學 Flutter
  • 17.
  • 18.
    怎樣學 Flutter • 建置環境,安裝IDE 與 SDK • 學習 Dart 程式語⾔與慣例 • 先動⼿寫⼀個 Flutter App 上⼿ • 熟悉 Flutter Widget • 熟悉 Flutter 的重要 Pattern 與更新機制 • 練習寫 Dart Package • 練習寫 Flutter Plugin
  • 19.
    安裝 IDE 與SDK • IDE • Android Studio • IntelliJ IDEA • Visual Studio Code • Flutter SDK https://flutter.dev/docs/get-started/install • Dart SDK https://dart.dev/get-dart
  • 20.
    學習 Dart 語⾔ •Learn X in Y minutes https://learnxinyminutes.com/docs/ dart/ • Dart Pad https://dartpad.dartlang.org • Exercism https://exercism.io • Effective Dart https://dart.dev/guides/language/effective- dart
  • 21.
    動⼿寫第⼀個 Flutter • Flutter的 New Project 就已經是⼀個簡單會動的程式了 • 官網教學 https://flutter.dev/docs/get-started/codelab • 《Flutter 實戰》第⼆章 https://book.flutterchina.club/ chapter2/
  • 22.
    Flutter Widgets • Flutter的 Widget 的數量非常多,考驗記憶⼒ • https://flutter.dev/docs/reference/widgets • https://flutter.dev/docs/development/ui/widgets • https://api.flutter.dev/flutter/widgets/widgets-library.html • 《實戰 Flutter》三~⼗章
  • 23.
    Flutter 的基本 Widget •Text、Image、Scaffold • Column、Row、Stack、List、Stack • Custom ScrollView • Container、Sized、Expanded、Flexible • Stream Builder、Future Builder
  • 24.
    Flutter 的 Pattern •先把你過去學過的 Mobile 開發忘了:MVC、 Singleton、Delegation… • 即使是 Dart 程式,與 Flutter 程式的典範不太⼀樣 • 在 Flutter 的應⽤程式中, 所有物件都在⼀顆樹裡頭
  • 25.
    Pattern? • Pattern 就是物件之間的關係 •不該有關係的就不要有關係 • Facade:某個 Class 包含了多個⼦系統,其他⼈都經過這個 介⾯,避免外部與⼦系統發⽣關係 • Singleton:某個 Class 只有⼀個 instance,其他⼈都 access 這個 instance 的多對⼀關係 • Delegate:某個 Class ⾃⼰不做事,交給另外⼀個物件的⼀對 ⼀關係
  • 26.
    Flutter Pattern • Flutter當中 Widget 只有三種關係: • 另⼀個 Widget 在當前的 Widget 上⽅ • 另⼀個 Widget 在當前的 Widget 下⽅ • 另⼀個 Widget 在當前 Widget 之外的另⼀顆樹裡頭 • 由上層節點決定下層節點的狀態
  • 27.
    往上尋找節點 • “of” • 往上尋找最接近且符合某個型態的節點 •Navigator.of(context).push(route) • Theme.of(context).primaryColor • MediaQuery.of(context).padding
  • 28.
    往下控制節點 • ⽬前 Widget的 build method 會產⽣下⽅的 Widget • 已經建立好了 Widget,想要知道內部的狀態,需要在建立 Widget 時 inject ⼀把 Key 進去 • 已經建立好了 Widget,想要改變下⽅ Widget 的狀態,除 了可以整個重 build,某些 Widget 也提供 controller
  • 29.
    另⼀個 Widget 在另⼀顆樹裡頭 • 先往上,再往下 •⽤ “of” 尋找同時位在這兩個 Widget 共同上⽅的 Widget • 由這個上⽅的 Widget 往下更新 • 越重要的資料(如登入狀態),放在越上⽅
  • 30.
    狀態管理 • UI =f(State) • Provider • Bloc (Business Logic Component)
  • 31.
    Dart Package 與 FlutterPlugin 開發 • stagehand • dart pub 發佈
  • 32.
  • 33.
    Android X • Android上使⽤ Gradle 管理 plugin 中的 native 部分 • 有些 plugin ⽤了 Android X,有些還在⽤ Android Support Library,然後就編不起來… • 發信請作者更新 plugin,或是⾃⼰ fork
  • 34.
    iOS 的 OpenGL •Flutter 在 iOS 上使⽤ OpenGL 繪製 UI • iOS 不會在背景更新 OpenGL 畫⾯,但是你的 App 可能會 在背景執⾏ • 如果你的 App 可能會在背景,就要在 native code 中保存狀 態,然後在 app 回到前景時更新 Flutter 畫⾯ • 混⽤ OpenGL 的 View,如 MapView,有時也會有靈異現象 • OpenGL 可能在⼀些很詭異的狀況下 Crash
  • 35.
    某些 plugin 跟你預期的⾏為不同 •有些 plugin 做了跟你預期不同的事情 • Local Notification plugin 與 Firebase Messaging plugin 打 架,某些訊息繪被 Local Notification plugin 攔走 • iOS 的 AppDelegate 事件不⼀定會交給哪個 plugin 處理 • 在 iOS 上,有時候要動⽤ Method Swizzling…
  • 36.
  • 37.
    Flutter 的測試 • Dart元件的單元測試 • Flutter Widget 的 Widget 測試 • 都有整合進 IDE 中 • 提供 Mockito 協助 Mock 資料
  • 38.
    Widget Test • 所有的native plugin 都得 mock 掉 • Flutter Widget test 單獨跑在 Dart VM 上,不提供 plugin 所需要的平台功能 • method channel 除了提供 setMethodCallHandler,也提供 setMockMethodCallHandler
  • 39.
    CI/CD • BitRise 對Flutter ⽀援非常好 • GitHub Actions/Travis 也適合⽤在 Dart Package 的 CI • 我們在內部使⽤ GitLab CI/Jenkins • Android 使⽤ Docker Image 編譯 • iOS 使⽤ Mac Mini 編譯
  • 40.
    Flutter 與 Native •Flutter 也可以透過 Plugin呼叫 iOS/Android 的 Native Code • Flutter -> Native:Method Channel • Native -> Flutter:Event Channel • 將 Native 畫⾯蓋在 Flutter 上:Platform View
  • 41.
    Recap • 什麼是 Flutter?Flutter如何加速產品開發? • 你是否應該導入 Flutter? • 新⼿怎樣學 Flutter? • 你可能會遇到的疑難雜症 • Flutter 的軟體⼯程
  • 42.
    學習資源 • Flutter 官網https://flutter.dev/ • Flutter 中⽂網 https://flutterchina.club/ • Flutter 官⽅ YouTube 頻道https://www.youtube.com/ channel/UCwXdFgeE9KYzlDdR7TG9cMw • ⼀堆 Twitter 帳號
  • 43.
    KKBOX OpenAPI SDKfor Dart https://pub.dev/packages/kkbox_openapi