GDG DevFest 2019
導入 Flutter 前你應該知道的事Weizhong Yang a.k.a zonble[email protected]
View Slide
關於我• 在 KKBOX ⼯作的⼯程師• 主要從事蘋果平台開發• 做過 KKBOX iOS、macOS、tvOS 版本,以及 KKTIX、Uta Pass 等產品,最近⽤ Flutter 做了 KKBOX Kids• GDE for Flutter
我們的經驗• 從 2018 年 Google I/O 之後開始接觸• 2018 年八⽉開始⽤ Flutter 做⼀些 SideProject• 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 RenderEngine• 沒有⽤到 UIKit 或是 Android UI Components,⽽是⽤⾃⼰的引擎繪製元件• 在不同平台上可以繪製出完全相同的 UI• 預設提供 Material 與 Cupertino 兩套 Widget
Flutter 如何加速開發?• 規劃新產品時,⽬前的趨勢是雙平台同時開發• 不同平台之間往往存在若⼲差異,同⼀套設計,在不同平台上可能各⾃有開發上困難的地⽅• 產品討論的時間不會少於實際開發的時間• Flutter 可以在不同平台使⽤同⼀套 UI 設計與 UIcodebase,省下討論的時間,直接進入產品開發
與 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/AndroidApp• 除了 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 SupportLibrary,然後就編不起來…• 發信請作者更新 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 的 NativeCode• 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 forDarthttps://pub.dev/packages/kkbox_openapi