Flutter & Native 混合開發

ZacJi發表於2020-02-21

Flutter & Native 混合開發

專案整合方案

問題

  1. 專案中仍有大量業務使用 Native 開發。專案引入 Flutter 後,要求所有 Native 開發者都配置 Flutter 開發環境並改動專案工程結構,會對開發效率造成影響。
  2. 引入 Flutter 後,混合專案的構建流程會發生變動。打包環境需要配置 Flutter 開發環境,且 Native 專案無法單獨構建。

需求

  1. 獨立開發環境
  2. 獨立構建

Flutter 專案模式

Flutter & Native 混合開發

  1. Flutter 模式就是純 Flutter 開發模式,原生專案被包在 Flutter 專案中,通過 Flutter 命令啟動專案,命令會先編譯 Flutter 工程,然後將 Flutter 編譯產物複製到 Native 專案中,接著編譯 Native ,最後啟動 Native ,Native 呼叫 Flutter 。

  2. module 模式,Flutter 工程只負責產出 Flutter 編譯產物,提供給 Native 工程使用。Flutter 和 Native 工程沒有程式碼和環境依賴,Native 工程只依賴 Flutter 的編譯產物。Flutter 工程和 Native 工程可以獨立編譯。

我們通過 flutter create 命令建立新的 Flutter 工程。這個命令有一個 --type 引數,通過傳入 module 這個引數 , 命令會為我們建立一個 module 型別的 Flutter 專案。它和普通的 Flutter 專案只有些許不同,我們可以通過專案結構窺探一二。

Flutter & Native 混合開發
Flutter & Native 混合開發

從上面的圖片可知,Flutter 專案模式和 module 模式在專案結構和檔案上差不多,但在 iOS 和 Android 這兩個和 Native 相關的資料夾上,Flutter 專案是直接將兩個資料夾暴露出來,而 module 模式則是選擇隱藏這兩個 Native 資料夾。很顯然,對於 Flutter 專案而言,Native 專案直接包在了 Flutter 專案中,必然需要在其中直接進行 Native 頁面和邏輯的開發。而 module 模式中,,整個 Flutter 工程是和 Native 工程隔離開的,原則上不應該有 Native 的邏輯程式碼,因而隱藏了 Native 相關檔案,不讓使用者有機會觸碰或者新增 Native 程式碼。

既然 module 模式和 Native 專案完全隔離, 為什麼還要保留一個隱藏的 Native 的專案呢?因為在 Native 平臺上,Flutter 無法獨立執行, 始終需要依附於一個 Native 專案才能夠啟動。因此為了在 module 模式下執行 App 進行除錯,必定需要一個 Native App 的空殼來調起 Flutter 頁面。

Native 呼叫 Flutter

要理解 module 模式如何工作,我們首先需要了解,一個純 Flutter 工程是如何被 Native App 引用並呼叫的。

Flutter for iOS 的產物:

  1. App.framework:Dart 業務原始碼相關檔案,以及專案依賴的靜態資源,如字型,圖片等
  2. Flutter.framework:Flutter 引擎庫檔案
  3. pubs 外掛目錄及用於索引的檔案:Flutter 下的外掛,包括各種系統的和自定義的channels

iOS Native 專案通過引入 Flutter.framework ,便可以呼叫 Flutter 專案中的程式碼,將 Flutter 嵌入到專案中。

Flutter for Android 的產物則是一個 flutter.aar,其中同樣包含了 Flutter 引擎庫以及專案中用到的靜態資源等。Android 工程通過直接引入 flutter.aar ,便可以呼叫 Flutter 專案中的程式碼。

從上面的實踐可知,只要我們取得了 Flutter for Native 的編譯產物,便可以輕鬆的將 Flutter 工程嵌入到現有的 Native 專案中。其中,iOS 相對簡單,直接將 Flutter 編譯出的幾個產物(Framwork、配置檔案) 拖入 Native 專案中即可呼叫。安卓則需要修改 Native 工程中的 gradle,新增 aar 中的 Flutter 依賴。

Native 接入 Flutter 實踐

目錄結構如下

some/path/ flutter_host_android/ flutter_host_ios/ flutter_module/

保持 Native 和 Flutter 工程入口在同一目錄下,三個工程各自由自己的 Git 進行版本管理。

flutter_module 目錄下包含了 Flutter 開發人員編寫的 Flutter 程式碼和 Flutter 的編譯產物。對於 Native 工程而言,他們不關心其中的 Flutter 程式碼,他們只需要將資源定位到其中的編譯產物,然後引入專案即可。

Android 引入 Flutter

在工程 settings.gradle 檔案中新增

//增加內容

setBinding(new Binding([gradle: this]))

evaluate(new File( settingsDir.parentFile,'flutter_module/.android/include_flutter.groovy' ))
複製程式碼

在工程 build.gradle 檔案中新增

dependencies {
.
.
implementation project(':flutter')
}
複製程式碼

當然配置完 gradle 後不要忘記同步。

需要注意的是,Flutter 開發人員在編寫完程式碼提交到 Git 之前,需要執行一次完整的 Flutter 專案,以便生成最新的編譯產物,否則 Native 端在呼叫 Flutter 時不會執行最新的程式碼。

當然,結偶性更好的方案是,只給 Native 開發人員提供 Flutter 產物,甚至使用 Cocoapods 這類包管理工具進行自動匯入和版本控制。大家可以根據自己的需求來實現具體的工程配置。

相關文章