背景
此篇文章搏存,主要針對想要在原有Native工程的基礎(chǔ)上集成Flutter的需求瑰步,所提供的混編方案的探討。
Flutter 官方已經(jīng)給出了混編方案:https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps#ios 這種方案有 優(yōu)點(diǎn)璧眠,也有 缺點(diǎn) 缩焦。
1. 官方方案的優(yōu)缺點(diǎn)
(1)優(yōu)點(diǎn):
- 不需要每次 Run 起來之后,先進(jìn)行 同步flutter代碼(組件化Flutter后责静,因?yàn)榻M件化后flutter代碼已經(jīng)變?yōu)閒ramework袁滥,所以每次進(jìn)來需要先熱更新同步代碼)
- 不需要單獨(dú)搞一個(gè)組件進(jìn)行集成,管理組件的版本灾螃,發(fā)布等题翻。
(2)缺點(diǎn):
會非常耦合工程,需要修改工程配置睦焕,添加 BUILD PHASE 調(diào)用 flutter 中 xcode_backend.sh 腳本 去編譯 Flutter藐握。
如果使用pod管理靴拱,那么還需修改xcconfig配置垃喊。
因?yàn)樾枰{(diào)用 Flutter 的編譯腳本,所以這種方式集成后袜炕,團(tuán)隊(duì)內(nèi)所有組員電腦和打包機(jī)本谜,都必須安裝Flutter環(huán)境才能編譯成功。
2. Flutter 組件化混編方案
(1)優(yōu)點(diǎn):
- 不需修改 原有 xcconfig 配置偎窘。
- 不需要添加 Run Script 腳本乌助。
- 運(yùn)行不需要依賴 Flutter 環(huán)境。
(2)缺點(diǎn)
- 需要單獨(dú)管理一個(gè) flutter私有索引庫陌知。
- 開發(fā)加載 Flutter 頁面 首次需要熱更新 進(jìn)行刷新同步 Flutter 代碼他托。
(3)混編方案 實(shí)現(xiàn)核心思想
- 通過查看 Flutter 編譯腳本
xcode_backend.sh
和 測試單獨(dú)引入編譯產(chǎn)物,發(fā)現(xiàn)其實(shí) 只要擁有 Flutter 的編譯產(chǎn)物仆葡,項(xiàng)目就可以接入 Flutter 的功能赏参。 - 所以說只要把Flutter編譯好的產(chǎn)物,放在工程里,那么就無需配置每次調(diào)用 xcode_backend.sh 腳本把篓,也無需強(qiáng)耦合Flutter環(huán)境纫溃,不需要所有組員安裝Flutter環(huán)境,只需要有發(fā)布開發(fā)需求的同學(xué)進(jìn)行安裝即可韧掩。
- 這就是Flutter組件化的實(shí)現(xiàn)核心點(diǎn)紊浩。
(4)Flutter 核心編譯產(chǎn)物
- App.framework:dart業(yè)務(wù)源碼相關(guān)文件,在 Debug 模式下就是一個(gè)很小的空殼疗锐,在 Release 模式下包含全部業(yè)務(wù)邏輯坊谁。
- flutter_assets:Flutter依賴的靜態(tài)資源,如字體滑臊,圖片等呜袁。
- Flutter.framework:Flutter庫和引擎。
目錄
- Flutter組件化 - 混編方案
- Flutter組件化 - 斷點(diǎn)調(diào)試
- Flutter組件化 - 發(fā)布更新
- Flutter組件化 - 一些坑點(diǎn)
一简珠、Flutter組件化 - 混編方案
1. Git倉庫存放 - 示例說明
主要分為3個(gè)倉庫阶界,分別存放Native項(xiàng)目、Flutter 工程源碼聋庵、Flutter 編譯產(chǎn)物私有pod庫膘融。
flutter 工程創(chuàng)建,使用 flutter create -t module my_flutter
命令
2. 項(xiàng)目目錄 - 示例
Flutter_iOS :iOS開發(fā)主項(xiàng)目。
flutter_library :Flutter 項(xiàng)目的開發(fā)源碼椒舵。
FlutterSDK :Flutter 源碼的編譯產(chǎn)物窄俏,所構(gòu)建的私有 pod 庫。
3. 混編方案說明
- 根據(jù) 只要擁有 Flutter 的編譯產(chǎn)物岛都,項(xiàng)目就可以接入 Flutter 的功能 的核心思想,我們?nèi)绻M(jìn)行組件化Flutter混編振峻,那么大概思路是:
有組件化環(huán)境 - 混編方案說明
(1)在 flutter 項(xiàng)目目錄下臼疫,執(zhí)行 flutter build ios 針對 Flutter 項(xiàng)目進(jìn)行編譯打包,生成 Flutter 編譯產(chǎn)物扣孟。
Flutter 的產(chǎn)物分為兩種模式烫堤,一個(gè)是 Debug 模式,采用 JIT(Just In Time)的方式凤价,好處是可以支持熱更新鸽斟,方便調(diào)試,,但是性能比較慢利诺。
另一種是 AOT(Ahead Of Time)release 模式富蓄,好處是性能比較好。
通過 flutter build ios --debug
可打包出 Debug 下的 Flutter 編譯產(chǎn)物慢逾。
flutter build ios 命令依賴于 Flutter 生成的 Runner 工程立倍,所以要確保 Runner 工程能夠編譯成功躏吊,這樣才能生成 flutter 編譯產(chǎn)物。如果遇到編譯失敗帐萎,可以檢查下 bundle id 修改一下比伏,使用自己的證書。如下圖示例:
(2)針對編譯產(chǎn)物疆导,制作 Flutter SDK 私有庫赁项, podspec 指定 App.framework、engine澈段、flutter_assets 路徑悠菜。
# podspec 有省略
Pod::Spec.new do |s|
s.name = "FlutterSDK"
s.vendored_frameworks = 'Framework/*.framework', 'Framework/engine/*.framework'
s.resources = 'Framework/flutter_assets'
end
(3)上傳 Flutter SDK 私有庫項(xiàng)目到云端私有pod索引庫。(如何制作私有 pod 索引庫败富,可搜索查看相關(guān)資料悔醋,這里不細(xì)說了)
(4)iOS 主項(xiàng)目指定 Podfile ,拉取云端Flutter私有庫到本地兽叮。
沒有組件化環(huán)境 - 混編方案說明
- 沒有組件化環(huán)境的項(xiàng)目芬骄,并且不會建立私有索引庫。
- 那么只有手動 執(zhí)行 flutter build ios 命令后鹦聪,將編譯產(chǎn)物手動拖拽到iOS項(xiàng)目中账阻。
4. 最后效果
如下圖,可以看到最終工程只引用了一個(gè)私有 pod 庫泽本。
總結(jié)
- 對 flutter 項(xiàng)目執(zhí)行 flutter build ios 命令淘太,生成編譯產(chǎn)物。
- 針對編譯產(chǎn)物规丽,制作為私有 pod 庫蒲牧。
- 主工程通過 cocoapods 引入私有 pod 庫。
二赌莺、Flutter 組件化 - 斷點(diǎn)調(diào)試
因?yàn)槭蔷幾g后的資源接入冰抢,我們還需要保證 Flutter 開發(fā)的同學(xué)可以正常調(diào)試。
目錄
- 單獨(dú)運(yùn)行 Flutter 工程調(diào)試
- 同時(shí)調(diào)試 iOS 和 Flutter(不支持?jǐn)帱c(diǎn))
- 同時(shí)調(diào)試 iOS 和 Flutter(支持?jǐn)帱c(diǎn))
注意點(diǎn):
- 確保雄嚣,已經(jīng)安裝 Android Studio(用于打開 Flutter 工程)
- 確保晒屎,項(xiàng)目中依賴的 Flutter 打包出來的是 Debug 版本喘蟆,Release 版本是無法熱更新和調(diào)試的(使用 flutter build ios --debug 打包 debug 版本)
1. 單獨(dú)運(yùn)行 Flutter 工程調(diào)試 (只適合和 Native 沒有太多關(guān)聯(lián)的工程缓升,比較少用)
使用 Android Studio 打開 Flutter 工程目錄
選擇好真機(jī)或者模擬器,然后點(diǎn)擊 Run 按鈕
這樣 Run 起來后蕴轨,我們就可以在 Flutter 項(xiàng)目中打斷點(diǎn)調(diào)試港谊。這種方法 只適合和 Native 沒有關(guān)聯(lián)的工程,比較少用橙弱。
2. 同時(shí)調(diào)試 iOS 和 Flutter(不支持Flutter斷點(diǎn)的方式)
這種方法歧寺,需要先打開 Xcode 運(yùn)行到 Flutter 頁面燥狰,再進(jìn)行附加 Flutter 端口號。
使用 Xcode 打開 iOS 項(xiàng)目斜筐,運(yùn)行起 Flutter 頁面龙致。
會發(fā)現(xiàn)會輸出一行日志,其中有一個(gè)端口號我們記錄下來顷链,例如:
flutter: Observatory listening on http://127.0.0.1:60455/
- 然后 使用 Android Studio 打開 Flutter 項(xiàng)目(不點(diǎn)擊運(yùn)行)目代,在 底部的 終端框中輸入 flutter attach --debug-port=60455,端口號替換為xcode 日志輸出的端口號嗤练。
Gif 演示
總結(jié)
- 先打開 iOS 工程榛了,運(yùn)行起 Flutter 頁面,得到一個(gè)日志輸出的端口號煞抬。
- 然后 Android Studio 打開 Flutter 工程霜大,在底部終端處輸入 flutter attach --debug-port=日志輸出端口號,然后附加成功即可革答。
- 注意點(diǎn):附加成功后战坤,在終端處,按小寫 r 只會刷新有有修改的文件残拐,按大寫的 R 會全部刷新湖笨,
如果使用組件化的話,每次進(jìn)入 Flutter 頁面蹦骑,Android Studio 附加成功后慈省,都要先按大寫 R 全部刷新一次 同步到最新代碼。否則還會顯示舊的頁面眠菇。
3. 同時(shí)調(diào)試 iOS 和 Flutter(同時(shí)支持Flutter 和 Xcode斷點(diǎn)的方式)
這種方法边败,需要先打開 Android Studio 選擇 Attach Debugger to Android Process 等待 Flutter 頁面連接,然后在 iOS 端捎废,運(yùn)行到 Flutter 頁面笑窜,Android Studio 就會附加成功。
首先打開 Flutter 工程登疗,直接點(diǎn)擊 Attach Debugger to Android Process排截,然后會等待 Flutter 頁面連接。
然后運(yùn)行 iOS 工程辐益,進(jìn)入 Flutter 頁面断傲。
然后就會發(fā)現(xiàn) Android Studio 已經(jīng)顯示在 同步文件了(
Syncing files to device 張大森的 iPhone...
)同步完成即連接成功。
注意坑點(diǎn)
- 我們可以看到 閃電符號
Flutter Hot Reload
和 返回綠色符號Flutter Hot Restart
- Flutter Hot Reload 為局部刷新智政,比如某個(gè)文件有改動认罩,才會同步刷新此頁面。Flutter Hot Restart可以理解為全部刷新续捂,在 Android Studio 面板上也有對應(yīng)按鈕垦垂,相應(yīng)也有對應(yīng)快捷鍵宦搬。
- 按照 Flutter 組件化的開發(fā)方式,我們首次附加連接成功后劫拗,一定要遵循一個(gè)步驟间校,先 點(diǎn)擊
Flutter Hot Restart
進(jìn)行全部刷新,再點(diǎn)擊Flutter Hot Reload
局部刷新页慷。因?yàn)楸救税l(fā)現(xiàn)撇簿,如果最后一次刷新點(diǎn)擊的是Flutter Hot Restart
按鈕,那么發(fā)現(xiàn)斷點(diǎn)會不生效差购,只有點(diǎn)擊Flutter Hot Reload
后 觸發(fā)的斷點(diǎn)才會生效四瘫。
演示 Gif
總結(jié)
- Android Studio 打開 Flutter 工程 ,點(diǎn)擊 Attach Debugger to Android Process
- 然后運(yùn)行 Flutter 頁面欲逃。
- 然后點(diǎn)擊
Flutter Hot Restart
(同步最新 Flutter 代碼)找蜜,在點(diǎn)擊Flutter Hot Reload
確保斷點(diǎn)能夠生效。
三稳析、Flutter組件化 - 發(fā)布更新
發(fā)布大概流程
(1)對 Flutter 工程 執(zhí)行 flutter build ios 或 flutter build ios --debug 生成編譯產(chǎn)物洗做。
(2)把編譯產(chǎn)物復(fù)制移動到 Flutter 私有庫目錄下。
(3)打包 上傳更新私有庫內(nèi)容彰居。
(4)主工程拉取最新版本诚纸。
版本更新說明
- 開發(fā)期間:基本只用熱更新進(jìn)行開發(fā)代碼。
- 發(fā)布版本:一般可在上線前進(jìn)行發(fā)布陈惰,所以組件版本更新畦徘,用的比較少。
四抬闯、一些坑點(diǎn)
(1)FlutterViewController 不釋放
- 加載 Flutter 頁面后井辆,返回后,VC 不會釋放溶握。閑魚有大神研究過這個(gè)問題杯缺,不過目前我們沒有找到解決方案去釋放 VC。
- 我們使用
單例持有了 VC
睡榆,只能做到不每次進(jìn)行疊加內(nèi)存萍肆,不重新創(chuàng)建。每次進(jìn)入 Flutter 頁面都先重置一下胀屿。 - 參考文章:http://www.reibang.com/p/9ff7a9a5dfec
(1)不支持x86_64
- 可以用xcode跑下塘揣,生成App.framewok,然后 lipo 命令合并下碉纳。
- 我們目前不支持模擬器勿负,這種方案沒有進(jìn)行測試。
其它
- 如果有更好的調(diào)試方法劳曹,坑點(diǎn)解決方法奴愉,混編方法,歡迎交流反饋下铁孵。
下一篇文章 (主要涉及到 Flutter 開發(fā)的一些知識)
- 教你 Flutter 如何與原生進(jìn)行交互
待更新