你好,我是陳航。
俗話說,工欲善其事,必先利其器。任何一門新技術、新語言的學習,都需要從最基礎的工程環境搭建開始,學習Flutter 也不例外。所以,作為專欄的第一篇文章,我會與你逐一介紹 Flutter 的開發環境配置,并通過一個 Demo 為
你演示 Flutter 項目是如何運行在 Andorid 和 iOS 的模擬器和真機上的。如果你已經掌握了這部分內容,那可以跳過
這篇預習文章,直接開始后面內容的學習。
由于是跨平臺開發,所以為了方便調試,你需要一個可以支持 Android 和 iOS 運行的操作系統,也就是 macOS,因
此后面的內容主要針對的是在 macOS 系統下如何配置Flutter 開發環境。
如果你身邊沒有 macOS 系統的電腦也沒關系,在Windows 或 Linux 系統上配置 Flutter 也是類似的方法,一些關鍵的區別我也會重點說明。但這樣的話,你就只能在Android 單平臺上開發調試了。
### 準備工作
#### 安裝 Android Studio
Android Studio 是基于 IntelliJ IDEA 的、Google 官方的Android 應用集成開發環境 (IDE)。
我們在官網上找到最新版(截止至本文定稿,最新版為3.4),下載后啟動安裝文件,剩下的就是按照系統提示進
行 SDK 的安裝和工程配置工作了。
配置完成后,我們打開 AVD Manager,點擊“Create Virtual Device”按鈕創建一臺 Nexus 6P 模擬器,至此Android Studio 的安裝配置工作就完成了。
#### 安裝 Xcode
Xcode 是蘋果公司官方的 iOS 和 macOS 應用集成開發環境 (IDE)。它的安裝方式非常簡單,直接在 macOS 系統的
App Store 搜索 Xcode,然后安裝即可。
安裝完成后,我們會在 Launchpad 看到 Xcode 圖標,打開它,按照提示接受 Xcode 許可協議,以及安裝配置組件就可以了。
配置完成后,我們打開 Terminal,輸入命令open -aSimulator打開 iOS 模擬器,檢查 Hardware>Device 菜單項中的設置,并試著在不同的模擬器之間做切換。
至此,Xcode 的安裝配置工作也就順利完成了。
#### 安裝 Flutter
Flutter 源站在國內可能不太穩定,因此谷歌中國開發者社區(GDG)專門搭建了臨時鏡像,使得我們的 Flutter 命令
行工具可以到該鏡像站點下載所需資源。
接下來,我們需要配置鏡像站點的環境變量。對于 macOS和 Linux 系統來說,我們通過文本編輯器,打開`
~/.bash_profile `文件,在文件最后添加以下代碼,來配置鏡像站點的環境變量:
```
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter
```
而對于 Windows 系統來說,我們右鍵點擊計算機圖標,依次選擇屬性–> 高級系統設置–> 高級–> 環境變量,新建用
戶變量 PUB_HOSTED_URL,其值為`https://pub.flutter-io.cn`;隨后新建 `FLUTTER_STORAGE_BASE_URL`,其值為https://storage.flutter-io.cn,重啟電腦即可完成配置。
到這里,我們就完成了鏡像的配置。
不過,由于 GDG 并不是官方組織,因此 Flutter 團隊也無法保證此服務長期可用。但是,你也不用擔心,可以關注
Flutter 社區 Using Flutter in China,來獲取其他可用的鏡像資源,隨時更新環境變量即可。
隨后,我們再去Flutter 官網,選擇并下載最新的穩定版(截止至本文定稿,最新穩定版為 1.5)。
接下來,我們把下載的壓縮包解壓到你想安裝的目錄,比如`~/Documents` 或 `C:\src\flutter`。為了可以在命令行中執行flutter 命令,我們同樣需要配置環境變量。
對于 macOS 與 Linux 系統,我們編輯~/.bash_profile 文件,把以下代碼添加至文件最后,將 flutter 命令的執行路
徑追加到環境變量 PATH 中:
```
export PATH=~/Documents/flutter/bin:$PATH
```
而對于 Windows 系統,我們在當前用戶變量下 Path,以 ;為分隔符,在其后追加 flutter 命令行的全路徑`
C:\src\flutter\bin`,重啟電腦即可完成配置。
到這里,我們就完成了 Flutter SDK 的安裝。
打開 Flutter 根目錄,我們可以發現有一個 examples 文件夾,里面是一些基本的 flutter 示例。在今天這篇文章中,
我會以 hello_world 示例為例,和你演示一下如何在模擬器和真機中運行 Flutter 項目。
首先,我給你介紹的是通過 Flutter 命令行運行的模式。進入 hello_world 目錄,輸入flutter emulators命令,查看
當前可用的模擬器:

:-: 圖 1 查看可用的 flutter 模擬器
可以看到,我們剛剛創建的兩臺模擬器,也就是 Nexus 6P和 iOS 模擬器都已經在列表中了。于是,我們啟動 iOS 模
擬器,運行 Flutter 項目:
```
flutter emulators --launch apple_ios_simulator
flutter run
```
等待 10 秒左右,一個熟悉的 hello world 大屏幕就出現在我們面前了:
圖 2 Flutter demo
Android 模擬器的啟動和運行,也與之類似,我就不再贅述
了。
不過,使用命令行的方式來開發調試 Flutter 還是非常不方便,更高效的方式是配置 Android 和 iOS 的集成開發環境。
Flutter 提供了一個命令`flutter doctor`協助我們安裝Flutter 的工程依賴,它會檢查本地是否有 Android 和 iOS的開發環境,如果檢測到依賴缺失,就會給出對應依賴的安裝方法。
接下來,我們試著運行下 flutter doctor 這條命令,得到了如下圖所示的結果:
:-: 
圖 3 flutter doctor 命令示意
可以看到,flutter doctor 檢測出了 iOS 工具鏈、Android Studio 工程這兩項配置中的問題。此外,由于我的電腦還
安裝了 IDEA 和 VS Code,而它們也是 Flutter 官方支持的IDE,因此也一并檢測出了問題。
接下來,我們根據運行 flutter doctor 命令得到的提示,來分別解決 iOS 工具鏈和 Android Studio 工程配置問題。
#### iOS 工具鏈設置
現在,我們已經可以在 iOS 模擬器上開發調試 Flutter 應用了。但要將 Flutter 應用部署到真實的 iOS 設備上,我們還
需要安裝一些額外的連接控制命令工具(就像通過電腦的iTunes 給手機安裝應用一樣),并申請一個 iOS 開發者賬
號進行 Xcode 簽名配置。
依據提示,我們首先安裝 libimobiledevice 和ideviceinstaller 這兩項依賴:
```
brew update
brew install --HEAD usbmuxd
brew link usbmuxd
brew install --HEAD libimobiledevice
brew install ideviceinstaller
```
其中,usbmuxd 是一個與 iOS 設備建立多路通信連接的socket 守護進程,通過它,可以將 USB 通信抽象為 TCP
通信;libimobiledevice 是一個與 iOS 設備進行通信的跨平臺協議庫;而 ideviceinstaller 則是一個使用它們在 iOS
設備上管理 App 的工具。
現在,你不了解它們的具體作用也沒關系,只要知道安裝了它們,Flutter 就可以進行 iOS 真機的開發調試就可以了。然后,進行 Xcode 簽名配置。
打開 hello_world 項目中的 ios/Runner.xcworkspace,在Xcode 中,選擇導航面板左側最上方的 Runner 項目。
:-: 
圖 4 Flutter Xcode 簽名配置
在General > Signing > Team 中,我們需要配置一下開發團隊,也就是用你的 Apple ID 登錄 Xcode。當配置完成
時,Xcode 會自動創建并下載開發證書。
任意 Apple ID 都支持開發和測試,但如果想將應用發布到App Store,則必須加入 Apple 開發者計劃。開發者計劃的
詳細信息,你可以通過蘋果官方的compare memberships了解,這里我就不再展開了。
最后,當我們第一次連接真機設備進行開發時,Xcode 會在你的帳戶中自動注冊這個設備,隨后自動創建和下載配置文件。我們只需要在真機設備上,按照手機提示,信任你的Mac 和開發證書就可以了。
至此,我們就可以在 iOS 真機上開發調試 Flutter 項目了。
#### Android 工具鏈配置
相對于 iOS 工具鏈的設置,Android 工具鏈配置就簡單多了,這是因為 Google 官方已經在 Android Studio 中提供
了 Flutter 和 Dart 這兩個插件。因此,我們可以通過這兩個工程插件,進行 Flutter 項目的管理以及開發調試。又因
為 Flutter 插件本身依賴于 Dart 插件,所以我們只安裝Flutter 插件就可以了。
:-: 
圖 5 Flutter 插件安裝
啟動 Android Studio,打開菜單項 Preferences >Plugins,搜索 Flutter 插件并點擊 install 進行安裝。安裝完畢后重啟 Android Studio,Flutter 插件就生效了。
由于 Android Studio 本身是基于 IDEA 開發的,因此IDEA 的環境配置與 Android Studio 并無不同,這里就不再贅述了。
對于 VS Code,我們點擊 View->Command Palette,輸入"install",然后選擇"Extensions:Install Extension"。在搜索框中輸入 flutter,選擇安裝即可。
至此,Android 的工具鏈配置也完成了。
盡管 Android Studio 是 Google 官方的 Android 集成開發環境,但借助于 Flutter 插件的支持,Android Studio 也因此具備了提供一整套 Flutter 開發、測試、集成打包等跨平臺開發環境的能力,而插件底層通過調用 Xcode 提供的命令行工具,可以同時支持開發調試及部署 iOS 和Android 應用。
因此,我后續的分享都會以 Android Studio 作為講解Flutter 開發測試的 IDE。
#### 運行 Flutter 項目
用 Android Studio 打開 hello_world 工程(Open an existing Android Studio Project),然后定位到工具欄:
:-: 
圖 6 Flutter 工具欄
在 Target selector 中,我們可以選擇一個運行該應用的設備。如果沒有列出可用設備,你可以采用下面的兩種方式:
參考我在前面講到的方法,也就是打開 AVD Manager并創建一臺 Android 模擬器;或是通過 open -a Simulator 命令,在不同的 iOS 模擬器之間進行切換。直接插入 Android 或 iOS 真機。
hello_world 工程稍微有點特殊,因為它提供了兩個 Dart啟動入口:一個英文版的 hello world-main.dart,和一個阿拉伯語版的 hello world-arabic.dart。因此,我們可以在Config selector 中進行啟動入口的選擇,也可以直接使用默認的 main.dart。
在工具欄中點擊 Run 圖標,稍等 10 秒鐘左右,就可以在模擬器或真機上看到啟動的應用程序了。
對于 Flutter 開發測試,如果每次修改代碼都需要重新編譯加載的話,那需要等待少則數十秒多則幾分鐘的時間才能查
看樣式效果,無疑是非常低效的。
正是因為 Flutter 在開發階段使用了 JIT 編譯模式,使得通過熱重載(Hot Reload)這樣的技術去進一步提升調試效率成為可能。簡單來說,熱重載就是在無需重新編譯代碼、
重啟應用程序、丟失程序執行狀態的情況下,就能實時加載修改后的代碼,查看改動效果。
>[info] 備注:我會在“02 | 預習篇 · Dart 語言概覽”中,與你分析 Flutter 使用 Dart 語言,同時支持 AOT 和 JIT。
就 hello_world 示例而言,為了體驗熱重載,我們還需要對代碼做一些改造,將其根節點修改為 StatelessWidget:
```
import 'package:flutter/widgets.dart';
class MyAPP extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const Center(child: Text('Hello World', text
}
}
void main() => runApp(new MyAPP());
```
點擊 Run 圖標,然后試著修改一下代碼,保存后僅需幾百毫秒就可以看到最新的顯示效果。
:-: 
圖 7 熱重載
是不是很 Cool!但是,熱重載也有一定的局限性,并不是所有的代碼改動都可以通過熱重載來更新。
對 hello_world 示例而言,由于 Flutter 并不會在熱重載后重新執行 main 函數,而只會根據原來的根節點重新創建控
件樹,因此我們剛才做了一些改造之后才支持熱重載。
關于 Flutter 熱重載的原理以及限制原因,我會在后面“34| Hot Reload 是怎么做到的?”文章,和你詳細分析。現在,你只需要知道,如果熱重載不起作用的時候,我們也不需要進行漫長的重新編譯加載等待,只要點擊位于工程面板左下角的熱重啟(Hot Restart)按鈕就可以以秒級的速度進行代碼重編譯以及程序重啟了,而它與熱重載的區別只是因為重啟丟失了當前程序的運行狀態而已,對實際調試也沒什么影響。
- 前言
- 開篇詞
- 預習篇
- 01丨預習篇 · 從0開始搭建Flutter工程環境
- 02丨預習篇 · Dart語言概覽
- Flutter開發起步
- 03丨深入理解跨平臺方案的歷史發展邏輯
- 04丨Flutter區別于其他方案的關鍵技術是什么?
- 05丨從標準模板入手,體會Flutter代碼是如何運行在原生系統上的
- Dart語言基礎
- 06丨基礎語法與類型變量:Dart是如何表示信息的?
- 07丨函數、類與運算符:Dart是如何處理信息的?
- 08丨綜合案例:掌握Dart核心特性
- Flutter基礎
- 09丨Widget,構建Flutter界面的基石
- 10丨Widget中的State到底是什么?
- 11丨提到生命周期,我們是在說什么?
- 12丨經典控件(一):文本、圖片和按鈕在Flutter中怎么用?
- 13丨ListView在Flutter中是什么?
- 14 丨 經典布局:如何定義子控件在父容器中排版位置?
- 15 丨 組合與自繪,我該選用何種方式自定義Widget?
- 16 丨 從夜間模式說起,如何定制不同風格的App主題?
- 17丨依賴管理(一):圖片、配置和字體在Flutter中怎么用?
- 18丨依賴管理(二):第三方組件庫在Flutter中要如何管理?
- 19丨用戶交互事件該如何響應?
- 20丨關于跨組件傳遞數據,你只需要記住這三招
- 21丨路由與導航,Flutter是這樣實現頁面切換的
- Flutter進階
- 22丨如何構造炫酷的動畫效果?
- 23丨單線程模型怎么保證UI運行流暢?
- 24丨HTTP網絡編程與JSON解析
- 25丨本地存儲與數據庫的使用和優化
- 26丨如何在Dart層兼容Android-iOS平臺特定實現?(一)
- 27丨如何在Dart層兼容Android-iOS平臺特定實現?(二)
- 28丨如何在原生應用中混編Flutter工程?
- 29丨混合開發,該用何種方案管理導航棧?
- 30丨為什么需要做狀態管理,怎么做?
- 31丨如何實現原生推送能力?
- 32丨適配國際化,除了多語言我們還需要注意什么
- 33丨如何適配不同分辨率的手機屏幕?
- 34丨如何理解Flutter的編譯模式?
- 35丨HotReload是怎么做到的?
- 36丨如何通過工具鏈優化開發調試效率?
- 37丨如何檢測并優化FlutterApp的整體性能表現?
- 38丨如何通過自動化測試提高交付質量?
- Flutter綜合應用
- 39丨線上出現問題,該如何做好異常捕獲與信息采集?
- 40丨衡量FlutterApp線上質量,我們需要關注這三個指標
- 41丨組件化和平臺化,該如何組織合理穩定的Flutter工程結構?
- 42丨如何構建高效的FlutterApp打包發布環境?
- 43丨如何構建自己的Flutter混合開發框架(一)?
- 44丨如何構建自己的Flutter混合開發框架(二)?
- 結束語
- 結束語丨勿畏難,勿輕略