對於已有工程想要嘗鮮 Flutter, 很多公司給出了最佳實踐方案, android 中是使用 aar 加入項目中, 這樣原生開發對於 flutter 環境就沒有要求了, 只要 flutter 打包后上傳 maven 即可, 但是這部分的過程坑很多, 后面我會再補充這種方案
我也摸索了一個實踐方案, 將所有項目的 aar 由 flutter 方打包 aar 后將 aar 置入某一個固定位置 ,並置入一個 git 庫管理, 然后 android 原生方直接 pull 后引入項目即可
高能預警: 本篇會結合 flutter, android, aar, gradle, maven, docker 的知識來完成所有的步驟
並不是每一個都會詳細說明, 如果有不明白的可以在 https://www.kikt.top 的本文下面留言, 我會更新文章或給予解答, 其他渠道的可能不會有時間看
開發環境
本人設備環境
MacOS 10.13.6 (17G65)
flutter: Flutter 1.5.4-hotfix.2 • channel stable
預計需要的環境
這些環境我默認你都有, 沒有的話本篇不講
windows 用戶? 對不住, 自己找尋其中的差別吧…
flutter
創建 flutter module
使用命令行創建:
$ flutter create -t module flutter_module
這里理論上會生成一個 aar
嗯,就這個東西
我們其實可以直接把這個 aar 放在宿主中,然后通過配置 aar 本地引用來直接使用這個工程, 但是這樣可能並不利於持續集成
所以我們要用到 maven 這個利器
ps: 這里有個坑, 就是純 flutter 項目可以, 但是如果你的 flutter 項目包含了對於第三方項目的依賴, 則 aar 可能不會包含其他的內容, 我們放在最后面再想辦法解決
maven 的處理方式(看看就行,作為錯誤嘗試的步驟)
本篇主要講的是 maven 的方式, 沒有原生 plugin 的很簡單, 但是有原生 plugin 的 flutter 步驟過於復雜, 最終沒實現, 當然理論上肯定是可以實現的
因為本篇講解的是本人解決 flutter 附着到已有工程的嘗試,所以將放棄的過程也記錄下來, 如果你只是想看最終的實現方案可以跳過本篇和后續所有涉及到 maven 的步驟
maven 是一個包管理工具
如果你公司有自己的私服, 則跳過這一章直接看下一章, 我這里只是使用 docker 創建一個 maven 私服環境
使用的鏡像是 sonatype/nexus3
配置
可選: $ docker pull sonatype/nexus3
我比較熟悉的有兩種方式:
命令行直接運行
使用 docker-compose
使用 docker-compose 就是類似於配置文件的方式
運行
在瀏覽器打開 http://localhost:8099
登錄的用戶名密碼,默認是 admin admin123
點開 maven, 毛也沒有
上傳 aar
使用 gradle 上傳 aar
使用 android studio 打開 flutter_module 下的.android 目錄, 經過一頓同步得到的可能是這樣的:一片空白毛都沒有…
這時候請 close, 重新打開, 現在是這個鬼樣子的
采用 project 視圖模式
在.android 下增加一個 gradle 文件,名字自取
比如我的就叫 update_aar.gradle
這個文件呢, 就是上傳用的 gradle 文件, 來源於網絡
前幾個 def 要根據你的 maven 來修改, 包名, 端口, 用戶名,密碼
接着引入 gradle 文件到項目中
修改: Flutter/build.gradle
按照下圖點擊
可能會報錯
似乎是由於路徑不對的原因, 請使用如下的方式修改 setting.gradle:
同步 gradle 后
接着雙擊
就可以上傳成功了
然后打開 nexus 查看: http://localhost:8099/#browse/search/maven
有顯示, 說明這個 aar 上傳是成功的
后面再上傳更改版本號即可
Android 項目(host)
新建項目
引入 maven 依賴
添加倉庫
根目錄 build.gradle, 根據節點增加一個 maven 倉庫:
引入庫, 在 nexus 的管理界面里可以查看引用方式:
接着在app/build.gradle
中修改
經過 sync 以后,使用 project 視圖, 可以找到這個庫:
編碼
新建 MyFlutterActivity.java
添加到清單文件
修改 MainActivity.java
這里模擬一進來直接進 FlutterActivity 的場景
建議你的 Android 同事在合適的時機調用 Flutter.startInitialization(this.getApplicationContext());
這個是官方給出的初始化 flutter 引擎的代碼, 否則首屏可能會慢
運行項目
初次運行可能會報錯 提示一個 androidO 什么的玩意
兩種方案
- minSDK 修改為 26, 這個簡直不科學
- 在 app/build.gradle 下的 android 節點下增加這個代碼
將源碼和目標代碼等級都設置為 1.8
嗯 這里插一句, 我的 host 使用的是 androidX, 而 flutter 使用的是 android.support, 所以需要按照 androidX 的遷移流程修改一下, 如果你新建項目的時候勾選了 androidX, 則這里應該不用修改
androidX 的問題可以查看我的另一篇文章, 雖然是 flutter 分類下的,但是對於普通 android 工程也適用
運行結果如下:
在 flutter 中添加帶有原生功能的庫
這里注意!!!!!!, 請先備份前面幾個文件
這里注意!!!!!!, 請先備份前面幾個文件
這里注意!!!!!!, 請先備份前面幾個文件
這里注意!!!!!!, 請先備份前面幾個文件
這里注意!!!!!!, 請先備份前面幾個文件
這里注意!!!!!!, 請先備份前面幾個文件
這里注意!!!!!!, 請先備份前面幾個文件
這里注意!!!!!!, 請先備份前面幾個文件
因為一旦 flutter packages get, 則 前面的文件就木有了
在 flutter 中添加庫
這里簡單舉例一下, 使用一個比較常用的shared_preferences
修改 flutter 的 yaml 文件
$ flutter packages get
這一步后, 之前的那幾個文件沒有了…
建議: 把 build.gradle 和 setting.gradle 復制到 module 級別的某個目錄下, 比如叫 template
然后用腳本來做這個上傳的事情
- 復制模板到對應目錄
- 通過環境變量設置 aar 的版本號
- 使用 gradle 命令來完成插件的調用
上傳新版本的 aar
修改版本號為 1.0.1
這里上傳成功了
到 android host 中用了一下, 果不其然和網上的朋友們說的一樣報錯了
查看對應的 pom.xml(我這里是 1.0.2),道理是一樣的
這里有一個 io.flutter.plugins.sharedpreferences 就是報錯的元凶了
思考解決方案
看到這里我感覺有如下的方案
- 將所有文件打包到同一個 aar 庫中, 然后再上傳(也就是網上那個 fat-aar 的方案)
- 修改 flutter 打包腳本, 然后將中間的三方庫產物(sp 插件)上傳至私服 maven, flutter 項目使用 api 的方式依賴這些庫, 完成 host=>flutter=>other plugin 的目的
- 不用 maven, 只用 aar
個人第一感覺, 覺得第一個實施起來可能會簡單一些, 先嘗試一下
fat-aar
這個找到了兩個項目:
一個 gradle 文件的方式: https://github.com/adwiv/android-fat-aar
一個是 plugin 的方式: https://github.com/Vigi0303/fat-aar-plugin
但是都要用到一個類似embed
這樣的關鍵字來替換 compile(api/implementation), 無奈找遍 gradle 沒找到修改的地方, 只能暫時放棄
flutter 的插件庫上傳至 maven
這個初始來看很可行.. 但仔細一想, 因為那個版本號的作祟, 需要改動的地方不算很少
每個插件包內的 gradle 文件都需要修改:
- 修改 version 版本號,這個應該是可以通過 環境變量/gradle 命令 來指定為佳, 不能指定的話理論上和 pub 的版本號相同也可以, 如果是 git 依賴, 就用 ref, path 依賴就很比較難自動取了
- 上傳腳本,這個要讀取上面的版本號, 還要讀取一個
為什么要修改版本號呢? flutter 依賴的插件的版本號會被帶到 aar 對應的 maven 庫中的 pom.xml 文件中
這里要插一句: pom.xml 中依賴的版本號是定義在每個插件自己的 build.gradle 中的,如下面的連接那樣
我這里說需要修改的就是這個版本號,否則你上傳 maven 的 flutter 庫的版本號和插件的 maven 版本號沒對上的話,依然會報錯
修改版本號並上傳需要遵循如下的步驟:
- 讀取本地
.flutter-plugins
文件的內容,將其中的版本號字段取出來 - 找到插件文件夾,替換掉版本號字段的內容
- 將上傳插件的腳本復制至對應文件夾,並將版本號,group 名與插件統一
- 啟動上傳腳本
- 將對原生文件的修改內容還原
為什么要做最后一步呢? 這種"從遠端"鏡像下來的東西,修改回去是一個好習慣, 因為修改了會破壞倉庫本身版本的完整性
解決方案-使用 aar 和 git 管理
這個就是我開篇說的解決方案, 不使用 maven, 只是打包出 aar, 集中起來, 置入 git 倉庫,如果有必要就打 tag 后 push 到遠端, 方便根據版本來引用
然后作為 android 原生方, 在 project 的 gradle 中引入 aar 庫即可, 當然如果你是大公司有自己的要求, 還是用上一種比較好
git 和 aar 引入也是很成熟的使用方案了, 無非就是如何拼接而已的問題, 何況這一步還可以通過 gradle 自動完成
處理 flutter 端
這次使用 dart 來作為腳本, 畢竟 dart 語言對於 flutter 開發者來說會很熟悉, 當然這一步可以用任何你熟悉的方式,比如: shell/python 等等, 這一步的執行需要將 dart 放入環境變量中
build_module.dart
: