huazi

huazi

淺談 Flutter 的 Android 混合開發

本篇文章為公司內部分享時所寫,基於的 flutter 版本也已過時,所以可能有不對的地方,還請指出。現在放到部落格上,以後有機會再完善。

前言#

Flutter 是谷歌的移動 UI 框架,可以快速在 iOS 和 Android 上構建高質量的原生用戶界面。 Flutter 可以與現有的代碼一起工作。
Flutter 具有以下特點:
快速開發,毫秒級的熱重載,修改後,您的應用界面會立即更新。
統一的應用開發體驗
原生性能
目前已經有不少大公司開始將 flutter 應用在項目中,比如,閒魚、美團等,也得到了不錯的反饋。
https://github.com/alibaba/flutter-go
文章暫時比較簡單,之後各個模塊可以細化

flutter 介紹及安裝#

對於構建 Flutter 類型應用,因其開發語言 Dart、虛擬機、構建工具與平時我們開發 Native 應用不同且平台虛擬機也不支持,所以需要 flutter sdk 來支持。
flutter 有點類似 gradle,不同的開發人員可能安裝不同版本的 flutter,flutter sdk 版本不一致,往往會出現 Dart 層 Api 兼容性或 Flutter 虛擬機不一致等問題。(這個問題可以參照 Android gradle 管理,將 gradle 版本跟項目綁定來處理)

具體 flutter sdk 安裝可以按照官方文檔來操作:https://flutter.dev/docs/get-started/install/macos
或者 flutter 中文文檔:https://flutterchina.club/setup-macos/

安裝基本沒有什麼坑,有牆的問題可以參考中文文檔使用 Flutter 官方為中國開發者搭建了臨時鏡像。

配置好就可以使用 flutter 的一些命令,比如 flutter doctor

Flutter 四種工程類型#

Flutter 工程中,通常有以下幾種工程類型,下面分別簡單概述下:

  1. Flutter Application
    標準的 Flutter App 工程,包含標準的 Dart 層與 Native 平台層

  2. Flutter Module
    Flutter 組件工程,僅包含 Dart 層實現,Native 平台層子工程為通過 Flutter 自動生成的隱藏工程

  3. Flutter Plugin
    Flutter 平台插件工程,包含 Dart 層與 Native 平台層的實現

  4. Flutter Package
    Flutter 純 Dart 插件工程,僅包含 Dart 層的實現,往往定義一些公共 Widget

已有項目使用 flutter#

已有的項目想改成純 flutter 項目基本不可能,目前只能是開發部分模塊功能使用,比如現在磁場項目中的體現功能。因此 flutter 官方出了向原生項目中添加 flutter 的項目:
https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps

目前想要的效果是:

  • 非 flutter 開發人員無感知
  • 對現有項目無侵入
  • 不需要對現有的持續集成和編譯發布進行修改
  • 方便 flutter 開發人員開發

官方的項目是將 flutter 項目作為 module 來依賴,但是這對項目修改太大,只適用於開發人員。因此我們需要考慮其他的方式。在文檔中我們知道,通過./gradlew flutter:assemble 是可以打包出 aar,這個 aar 其實是 flutter 生成的產物打包成 aar,來供項目使用的。我們可以利用這個,來只使用 aar,這樣基本滿足了上面的部分條件。但是如果是每次生成一個 aar 再拷貝到主項目 libs 下,這樣每次處理太麻煩了,如果能將 aar 進行遠程依賴就更好了,上面的要求基本就都滿足了,對原生項目來說只是一個遠程依賴而已,需要更新時則修改版本號即可。

至此,我們梳理出流程:

  • flutter aar 作為遠端依賴
  • 本地有配置是否是 flutter 開發環境
    • 開啟開發環境,則使用本地依賴方式
    • 關閉開發環境,使用遠端依賴
    • 默認關閉
  • flutter 項目可自動打包上傳 aar 至遠端倉庫

flutter module 的項目結構如下圖:

flutter_android_img.jpeg

.android 和 .ios 都是自動生成的,可以隨時刪除,通過flutter packages get 獲取, flutter 代碼主要在 lib 下。注意在.android 和.ios 目錄下都有一個 Flutter 目錄,這個是我們 flutter 的庫項目了。也就是 Android 用來生成 aar,iOS 用來生產 framework 的庫。如果我們用 flutter create xxx 生成的純 flutter 項目是沒有這個 Flutter 目錄的。

開發遇到的坑#

  1. 項目配置 productFlavor,導致無法將 flutter_assets 打包進 apk

其實這個是 flutter 的新版的 bug,flutter 的構建都是通過 flutter.gradle 來進行的,新的版本中做了一些改變,以為其中硬編碼的原因,導致配置了 productFlavor 後無法執行某些 task,也就沒有無法將 flutter_assets 打包進 apk。從而引起崩潰。

做了個臨時解決方案:

  • 創建代理 flutter 構建的 gradle 文件,即 flutter_proxy.gradle,從 flutter.gradle 複製而來
  • 修改其關於配置了 productFlavor 後的執行 task 的邏輯,確保執行相關 productFlavor 的打包 task
  • build.gradle 中替換 flutter.gradleflutter_proxy.gradle

這樣就可以正常使用 gradle 打包了,缺點就是每次 flutter package get 需要重新改

註:該 Bug 在新版 flutter sdk 中已修復

  1. 還有個疑問就是 ./gradlew flutter:assemble 打出的 aar 安裝後,原生頁面打開 flutter 頁面時崩潰,但是打包命令去掉 flutter 卻可以,即 ./gradlew assemble,猜測跟打包流程有關係,暫時沒有深入去研究

  2. appbar 設置屬性時默認設置了狀態欄
    解決辦法:單獨調整狀態欄屬性,或修改主題

  3. flutter 項目中默認生成的 build.gradle 中依賴的是 support 27.1.1,目前項目中使用的是 26.1.0,導致包依賴衝突

對於遠端依賴時可以移除他的 support 依賴,如下:

implementation('com.huazidev:test-futter-aar:0.0.2@aar', {
     exclude group: 'com.android.support'
})

對於本地開發環境可以做如下配置:

implementation(project(':flutter')){
      exclude group: 'com.android.support'
}

另外,也可以在 gradle 中統一修改所有的 support 依賴版本,


下一章,待完善#

  • 編寫腳本,自動打包發布 aar
  • 發布到 jcenter 、maven 等開源倉庫
  • 發布到自建的私有 maven 倉庫
  • 使用 jitpack 發布 (私有倉庫收費)
  • 使用 github 提供的功能作為包管理倉庫(支持私有倉庫)
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。