前言:
Flutter 因其自建的渲染引擎,背靠谷歌的支持,近來(lái)俘獲了不少的開發(fā)小伙伴,越來(lái)越多的開發(fā)者嘗試使用Flutter進(jìn)行開發(fā),在原生項(xiàng)目中嵌入Flutter來(lái)完成復(fù)雜度不高的頁(yè)面成為了一個(gè)不錯(cuò)的選擇。本篇文章記錄了一次在原生項(xiàng)目中嵌入Flutter的過(guò)程。
準(zhǔn)備工作:搭建好 Flutter 的開發(fā)環(huán)境
[簡(jiǎn)書抽風(fēng)可能無(wú)法顯示]
在原生項(xiàng)目中加入Flutter模塊
之前網(wǎng)上對(duì)混合開發(fā)有一些現(xiàn)成的庫(kù),目前效果不是很理想,本文采用的是官方文檔中的方法。
1. 創(chuàng)建 Flutter 模塊
到需要?jiǎng)?chuàng)建模塊的文件夾下(本文為原生項(xiàng)目下),執(zhí)行創(chuàng)建模塊的命令:
$: flutter create --template module flutter_moudle
// 此處根據(jù)網(wǎng)絡(luò)狀況可能會(huì)耗時(shí)很久,耐心等待即可。
創(chuàng)建成功后,能在目下看到一個(gè) flutter_moudle 的文件:
Tips:
- 使用"shift+cmd+."可查看文件夾隱藏文件
2. 配置 Flutter 模塊
官方在項(xiàng)目中啟用Flutter模塊提供了多種方法,本文主要介紹其中兩種:
(1)方法1: CocoaPods
在Podfile中添加定義,并配置對(duì)應(yīng)的Target
添加如下兩句到定義:
# flutter模塊的路徑(本文的flutter模塊與Podfile在同一目錄下)
flutter_application_path = 'flutter_moudle'
# 加載podhelper.rb
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb’)
# 配置對(duì)應(yīng)Target:
target 'MyApp' do
install_all_flutter_pods(flutter_application_path)
end
添加完畢后執(zhí)行更新項(xiàng)目的pod
$: pod install
完成后打開原生項(xiàng)目的 xxx.xcworkspace ,可以看到Pods新增DevelopmentPods文件:
(2)方法2: Framework
進(jìn)入到我們第一步創(chuàng)建的Flutter組件的文件中,將相應(yīng)的模塊添加到原生項(xiàng)目的Framework即可,對(duì)應(yīng)模塊為:
- flutter.framework (路徑:/flutter_moudle/.ios/Flutter/App.framework)
- app.framework (路徑:/flutter_moudle/.ios/Flutter/engine/Flutter.framework)
使用兩種方法任何一種均可,配置完成后執(zhí)行編譯(cmd+b),編譯成功后表示我們已經(jīng)成功將Flutter加入到了原生項(xiàng)目中。
Tips1:
【Bitcode 相關(guān)】
默認(rèn)情況下,原生項(xiàng)目是開啟了Bitcode選項(xiàng)的,而 Flutter 目前并不支持,需要手動(dòng)關(guān)閉(Build Setting -> Enable Bitcode 設(shè)置為 NO)
Tips2:**
【編譯報(bào)錯(cuò):Command PhaseScriptExecution failed with a nonzero exit code】**:
這個(gè)錯(cuò)誤發(fā)生在原生項(xiàng)目的文件名改變后,錯(cuò)誤信息還提示了“flutter/XXXX/XXX no such file found”的內(nèi)容,說(shuō)明找不到Flutter路徑了,我們看到在 .ios/Flutter/Generated.xcconfig 中看到了Flutter的各種路徑,而我們改變文件名后,還需要更新Flutter配置,可在 “.ios” 目錄下使用自動(dòng)更新命令:
$: flutter pub get
Tips3:**
【編譯卡死在:/Users/xurenjie/Desktop/AppStore/ProjectName/flutter_moudle/.ios/Flutter/flutter_export_environment.sh: line 8: inherited: command not found】**
該問(wèn)題在多次編譯項(xiàng)目后出現(xiàn),頻率較高,可臨時(shí)通過(guò)清除項(xiàng)目緩存解決。
使用Flutter
預(yù)熱并配置 Flutter 引擎
調(diào)用Flutter頁(yè)面
然后在需要展示 Flutter 頁(yè)面的時(shí)候使用 FlutterViewController:
至此,我們就完成了在原生應(yīng)用中加入Flutter模塊的配置
熱重載
熱重載是 Flutter 的一大特性,在VSCode,AndroidStudio中開發(fā)時(shí)可以很容易的使用,而在Xcode下,打開熱重載的方式:
[方法1]
此方法必須等APP中成功啟動(dòng)了FlutterEngin后才能生效,本文的FlutterEngin在AppDelegate中項(xiàng)目啟動(dòng)時(shí)就啟動(dòng)了,所以運(yùn)行項(xiàng)目后,可直接在flutter模塊的文件中(本文模塊文件為flutter_moudle)運(yùn)行命令:
$ flutter attach
調(diào)試時(shí)需要使用:
$ flutter attach --isolate-filter='debug'
[方法2]
此方法可以等待項(xiàng)目中的flutter engin啟動(dòng),不同1那種需要在啟動(dòng)的情況下才可以啟用:
在VSCode中運(yùn)行:
$ Attach to Flutter on Device
Tips:
【isolate相關(guān)錯(cuò)誤】
需要在main.dart的main函數(shù)添加如下設(shè)置:
isolate錯(cuò)誤解決方式
總結(jié)
- 可以看到,將Flutter加入到原生項(xiàng)目中非常簡(jiǎn)單。
- Flutter 也給項(xiàng)目的開發(fā)增加了復(fù)雜度,一方面使得開發(fā)團(tuán)隊(duì)必須形成規(guī)范,以在Android、iOS、Flutter、Web均存在的項(xiàng)目中不會(huì)發(fā)生混合開發(fā)的坑。
- Flutter的優(yōu)點(diǎn)在于一次開發(fā),多處使用,且借助其自建引擎在不同平臺(tái)上都有接近于原生的表現(xiàn)。
- 明顯的是,引入Flutter會(huì)明顯直接增大包體積。
- 加入Flutter的原生項(xiàng)目的編譯速度降低,尤其是初次編譯非常明顯,不嚴(yán)謹(jǐn)?shù)挠眯№?xiàng)目測(cè)試多次,加入前初次編譯不到20s左右,而加入后最長(zhǎng)的一次等待了5分鐘,(可能是提醒我該換電腦了)。
- 鑒于上述情況,將Flutter加入開發(fā)中,需要根據(jù)項(xiàng)目當(dāng)下的實(shí)際情況(團(tuán)隊(duì)成員技術(shù)構(gòu)成,項(xiàng)目業(yè)務(wù)特點(diǎn)等等)確定,不可一概而論,也不可能一勞永逸。