無需 script listening module create 示例 and 路徑 教你

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

背景

此篇文章,主要針對想要在原有Native工程的基礎上集成Flutter的需求,所提供的混編方案的探討。

  1. 官方方案的優缺點

(1)優點:

不需要每次 Run 起來之後,先進行 同步flutter代碼(組件化Flutter後,因為組件化後flutter代碼已經變為framework,所以每次進來需要先熱更新同步代碼)
不需要單獨搞一個組件進行集成,管理組件的版本,發布等。
(2)缺點:

會非常耦合工程,需要修改工程配置,添加 BUILD PHASE 調用 flutter 中 xcode_backend.sh 腳本 去編譯 Flutter。
如果使用pod管理,那麽還需修改xcconfig配置。
因為需要調用 Flutter 的編譯腳本,所以這種方式集成後,團隊內所有組員電腦和打包機,都必須安裝Flutter環境才能編譯成功。

  1. Flutter 組件化混編方案

(1)優點:

不需修改 原有 xcconfig 配置。
不需要添加 Run Script 腳本。
運行不需要依賴 Flutter 環境。
(2)缺點

需要單獨管理一個 flutter私有索引庫。
開發加載 Flutter 頁面 首次需要熱更新 進行刷新同步 Flutter 代碼。
(3)混編方案 實現核心思想

通過查看 Flutter 編譯腳本xcode_backend.sh 和 測試單獨引入編譯產物,發現其實 只要擁有 Flutter 的編譯產物,項目就可以接入 Flutter 的功能。
所以說只要把Flutter編譯好的產物,放在工程裏,那麽就無需配置每次調用 xcode_backend.sh 腳本,也無需強耦合Flutter環境,不需要所有組員安裝Flutter環境,只需要有發布開發需求的同學進行安裝即可。
這就是Flutter組件化的實現核心點。
(4)Flutter 核心編譯產物

App.framework:dart業務源碼相關文件,在 Debug 模式下就是一個很小的空殼,在 Release 模式下包含全部業務邏輯。
flutter_assets:Flutter依賴的靜態資源,如字體,圖片等。
Flutter.framework:Flutter庫和引擎。
目錄

Flutter組件化 - 混編方案
Flutter組件化 - 斷點調試
Flutter組件化 - 發布更新
Flutter組件化 - 一些坑點
一、Flutter組件化 - 混編方案

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

  1. Git倉庫存放 - 示例說明

主要分為3個倉庫,分別存放Native項目、Flutter 工程源碼、Flutter 編譯產物私有pod庫。

flutter 工程創建,使用 flutter create -t module my_flutter 命令

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

  1. 項目目錄 - 示例

Flutter_iOS :iOS開發主項目。
flutter_library :Flutter 項目的開發源碼。
FlutterSDK :Flutter 源碼的編譯產物,所構建的私有 pod 庫。
Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

  1. 混編方案說明

根據 只要擁有 Flutter 的編譯產物,項目就可以接入 Flutter 的功能 的核心思想,我們如果進行組件化Flutter混編,那麽大概思路是:
有組件化環境 - 混編方案說明

(1)在 flutter 項目目錄下,執行 flutter build ios 針對 Flutter 項目進行編譯打包,生成 Flutter 編譯產物。

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

Flutter 的產物分為兩種模式,一個是 Debug 模式,采用 JIT(Just In Time)的方式,好處是可以支持熱更新,方便調試,,但是性能比較慢。

另一種是 AOT(Ahead Of Time)release 模式,好處是性能比較好。

通過 flutter build ios --debug 可打包出 Debug 下的 Flutter 編譯產物。

flutter build ios 命令依賴於 Flutter 生成的 Runner 工程,所以要確保 Runner 工程能夠編譯成功,這樣才能生成 flutter 編譯產物。如果遇到編譯失敗,可以檢查下 bundle id 修改一下,使用自己的證書。如下圖示例:

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

(2)針對編譯產物,制作 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 私有庫項目到雲端私有pod索引庫。(如何制作私有 pod 索引庫,可搜索查看相關資料,這裏不細說了)

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

(4)iOS 主項目指定 Podfile ,拉取雲端Flutter私有庫到本地。

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

沒有組件化環境 - 混編方案說明

沒有組件化環境的項目,並且不會建立私有索引庫。
那麽只有手動 執行 flutter build ios 命令後,將編譯產物手動拖拽到iOS項目中。

  1. 最後效果

如下圖,可以看到最終工程只引用了一個私有 pod 庫。

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

總結

對 flutter 項目執行 flutter build ios 命令,生成編譯產物。
針對編譯產物,制作為私有 pod 庫。
主工程通過 cocoapods 引入私有 pod 庫。
二、Flutter 組件化 - 斷點調試

因為是編譯後的資源接入,我們還需要保證 Flutter 開發的同學可以正常調試。

目錄

單獨運行 Flutter 工程調試
同時調試 iOS 和 Flutter(不支持斷點)
同時調試 iOS 和 Flutter(支持斷點)
註意點:

確保,已經安裝 Android Studio(用於打開 Flutter 工程)
確保,項目中依賴的 Flutter 打包出來的是 Debug 版本,Release 版本是無法熱更新和調試的(使用 flutter build ios --debug 打包 debug 版本)

  1. 單獨運行 Flutter 工程調試 (只適合和 Native 沒有太多關聯的工程,比較少用)

使用 Android Studio 打開 Flutter 工程目錄

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

選擇好真機或者模擬器,然後點擊 Run 按鈕

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

這樣 Run 起來後,我們就可以在 Flutter 項目中打斷點調試。這種方法 只適合和 Native 沒有關聯的工程,比較少用。

  1. 同時調試 iOS 和 Flutter(不支持Flutter斷點的方式)

這種方法,需要先打開 Xcode 運行到 Flutter 頁面,再進行附加 Flutter 端口號。

使用 Xcode 打開 iOS 項目,運行起 Flutter 頁面。
Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

會發現會輸出一行日誌,其中有一個端口號我們記錄下來,例如:
flutter: Observatory listening on http://127.0.0.1:60455/
然後 使用 Android Studio 打開 Flutter 項目(不點擊運行),在 底部的 終端框中輸入 flutter attach --debug-port=60455,端口號替換為xcode 日誌輸出的端口號。
Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

Gif 演示

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

總結

先打開 iOS 工程,運行起 Flutter 頁面,得到一個日誌輸出的端口號。
然後 Android Studio 打開 Flutter 工程,在底部終端處輸入 flutter attach --debug-port=日誌輸出端口號,然後附加成功即可。
註意點:附加成功後,在終端處,按小寫 r 只會刷新有有修改的文件,按大寫的 R 會全部刷新,如果使用組件化的話,每次進入 Flutter 頁面,Android Studio 附加成功後,都要先按大寫 R 全部刷新一次 同步到最新代碼。否則還會顯示舊的頁面。

  1. 同時調試 iOS 和 Flutter(同時支持Flutter 和 Xcode斷點的方式)

這種方法,需要先打開 Android Studio 選擇 Attach Debugger to Android Process 等待 Flutter 頁面連接,然後在 iOS 端,運行到 Flutter 頁面,Android Studio 就會附加成功。

首先打開 Flutter 工程,直接點擊 Attach Debugger to Android Process,然後會等待 Flutter 頁面連接。
Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

然後運行 iOS 工程,進入 Flutter 頁面。
然後就會發現 Android Studio 已經顯示在 同步文件了(Syncing files to device 張大森的 iPhone...)
同步完成即連接成功。
Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

註意坑點

我們可以看到 閃電符號 Flutter Hot Reload 和 返回綠色符號 Flutter Hot Restart
Flutter Hot Reload 為局部刷新,比如某個文件有改動,才會同步刷新此頁面。Flutter Hot Restart可以理解為全部刷新,在 Android Studio 面板上也有對應按鈕,相應也有對應快捷鍵。
按照 Flutter 組件化的開發方式,我們首次附加連接成功後,一定要遵循一個步驟,先 點擊 Flutter Hot Restart 進行全部刷新,再點擊 Flutter Hot Reload 局部刷新。因為本人發現,如果最後一次刷新點擊的是 Flutter Hot Restart 按鈕,那麽發現斷點會不生效,只有點擊 Flutter Hot Reload 後 觸發的斷點才會生效。
Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學
Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學
演示 Gif

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

打斷點.gif
總結

Android Studio 打開 Flutter 工程 ,點擊 Attach Debugger to Android Process
然後運行 Flutter 頁面。
然後點擊Flutter Hot Restart (同步最新 Flutter 代碼),在點擊 Flutter Hot Reload 確保斷點能夠生效。
三、Flutter組件化 - 發布更新

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學
發布大概流程

(1)對 Flutter 工程 執行 flutter build ios 或 flutter build ios --debug 生成編譯產物。

(2)把編譯產物復制移動到 Flutter 私有庫目錄下。

(3)打包 上傳更新私有庫內容。

(4)主工程拉取最新版本。

版本更新說明

開發期間:基本只用熱更新進行開發代碼。
發布版本:一般可在上線前進行發布,所以組件版本更新,用的比較少。
四、一些坑點

(1)FlutterViewController 不釋放

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學

加載 Flutter 頁面後,返回後,VC 不會釋放。閑魚有大神研究過這個問題,不過目前我們沒有找到解決方案去釋放 VC。
我們使用單例持有了 VC,只能做到不每次進行疊加內存,不重新創建。每次進入 Flutter 頁面都先重置一下。

(1)不支持x86_64

可以用xcode跑下,生成App.framewok,然後 lipo 命令合並下。
我們目前不支持模擬器,這種方案沒有進行測試。
其它

如果有更好的調試方法,坑點解決方法,混編方法,歡迎交流反饋下。
下一篇文章 (主要涉及到 Flutter 開發的一些知識)

教你 Flutter 如何與原生進行交互 待更新
最近有很多粉絲反映怎麽學好java? java開發技術不是一兩天就能學好的關鍵是你看怎麽學 跟誰去學,俗話說的好師傅領進門,修行靠個人,這個不是短時間類所能完成的任務,有想法的上方關註,下方留言“學習”我教你!

Flutter 開發集合系列之優雅的 Flutter 組件化 混編方案大神必學