把Flutter做爲一個模塊接入到現有的Android工程,Flutter有官方推薦方案 Add Flutter to existing apps,經過這樣的工程配置,能夠在debug支持HotReload,也能夠輸出Release包供發佈。不過在使用過程當中有一些須要調整的地方,特此記錄但願對你們能有借鑑意義。android
flutter create -t modulegit
命令會建立一個支持Flutter的Android Library,其中Android Library的目錄位於Flutter工程的隱藏目錄 .android/flutter 中, 通常狀況下,咱們會把Flutter代碼和Android代碼放在兩個git倉庫,經過submodule的方式進行依賴,能夠把這個Library的代碼copy到你的工程目錄下,同時修改flutter的資源目錄到你本身的相對路徑下:github
flutter { source ' your own flutter project directory ' }緩存
另外須要Copy include_flutter.groovy 這個文件到你的工程目錄下,修改相應的目錄添加對於Library的依賴。bash
Flutter官方只提供了四種CPU架構的SO庫:armeabi-v7a、arm64-v8a、x86和x86-64。可是目前咱們對接的兩個項目組分別是隻支持armeabi和只支持armeabi-v7a,因此須要對官方的jar包進行改造。官方SDK提供的jar包路徑在 $flutterRoot/bin/cache/artifacts/engine中,複製這幾個目錄下的armeabi-v7a中的so到armeabi路徑下:架構
能夠經過以下腳本實現:app
unzip flutter.jar lib/armeabi-v7a/libflutter.so
mkdir lib/armeabi
cp lib/armeabi-v7a/libflutter.so lib/armeabi/libflutter.so
zip flutter.jar lib/armeabi-v7a/libflutter.so lib/armeabi/libflutter.so
複製代碼
Library中的build.gradle中有一段是經過本地的一個gradle文件添加flutter.jar的依賴:測試
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
複製代碼
咱們把flutter.gradle文件以及咱們剛纔處理的flutter.jar文件Copy到本身的工程路徑下,我本身的工程路徑配置以下:gradle
project
│ app
└───flutter
│ │ build.gradle
│ │ flutter.gradle
│ │ include_flutter.groovy
│ └───flutter-jars
│ └───android-arm
| | flutter.jar
│ └───android-arm-dynamic-profile
| | flutter.jar
│ └───android-arm-dynamic-release
| | flutter.jar
| └───android-arm-profile
| | flutter.jar
| └───aandroid-arm-release
| | flutter.jar
│ settings.gradle
複製代碼
將flutter.gradle 中jar文件的路徑改成本地工程:ui
debugFlutterJar = new File('flutter-jars/debug/flutter.jar')
profileFlutterJar = new File('flutter-jars/profile/flutter.jar')
releaseFlutterJar = new File('flutter-jars/release/flutter.jar')
dynamicProfileFlutterJar = new File('flutter-jars/dynamicProfile/flutter.jar')
dynamicReleaseFlutterJar = new File('flutter-jars/dynamicRelease/flutter.jar')
複製代碼
這樣打出的AAR就能同時支持兩種架構。
按照上面的配置,能夠在工程中打出支持Debug HotReload和Release的包,不過在輸出AAR給別的業務模塊使用時會報一個崩潰:
must be able to initialize the ICU context.
這是Android Gradle Plugin 3.+ 版本的一個bug,它會丟棄flutter.jar 中的 /assets/flutter_shared/icudtl.dat文件到AAR中,致使運行時找不到這個文件崩潰,在2.+版本中發現沒有這個問題,因此須要使用Android Gradle Plugin 2.+版本,我這邊測試2.2.3版本是ok的。可是Android Gradle 2的版本有一個由來已久的問題就是Library不能獲取project一致 的BuildType,Library默認只發布Release的AAR。這是由於Android中默認指定了發佈type:
private String defaultPublishConfig = "release";
private boolean publishNonDefault = false;
複製代碼
默認Release,而flutter.gradle中經過buildtype來肯定flutter的buildmode,在Android Gradle Plugin 3.+版本中,這個buildtype的問題已經獲得解決,這也多是flutter選用3.+版本的一個緣由。
若是避免2.+的buildtype問題呢,網上是有一些獲取project的buildtype配置給Library的方案,好比如何讓library的buildType類型跟app的buildType類型一致(自由定義library的buildType) ??。 個人實現方案是擯棄經過buildtype肯定flutter的buildmode的方案,經過直接讀取本地local.properties中的參數來決定,這樣須要本身在本地手動的進行mode的切換,尤爲是要注意上線的時候修改成Release模式。不過debug模式下頁面有明顯的debug標識,因此通常也不會出錯。將flutter.gradle 中原有的buildmodefor方法:
private static String buildModeFor(buildType) {
if (buildType.name == "profile") {
return "profile"
} else if (buildType.name == "dynamicProfile") {
return "dynamicProfile"
} else if (buildType.name == "dynamicRelease") {
return "dynamicRelease"
} else if (buildType.debuggable) {
return "debug"
}
return "release"
}
複製代碼
修改成:
private String buildModeFor(Project project) {
return resolveProperty(project, 'flutter.buildMode', 'release')
}
複製代碼
這樣在local.properties 中就能夠進行debug和Release的切換:
flutter.buildMode=release
flutter.buildMode=debug
在第一次配置好工程或者切換mode的過程當中,可能會遇到如下的崩潰問題:
Check failed: vm. Must be able to initialize the VM.
主要是因爲不一樣模式下的產物沒有清理使用了緩存,解決辦法是刪除掉全部build文件的內容再全量編譯一次就能夠了。
這是我在作flutter工程配置中遇到的一些坑,文風偏流水帳,請你們見諒,只但願能對你們有一些借鑑意義。另外,咱們已經在項目的兩個模塊中使用了flutter,開發效率確實能有很大提升,畢竟兩端只須要一我的開發就ok,並且UI小姐姐要求的頁面效果都能徹徹底底的完成,上線以後目前還沒發現什麼問題。下一步須要作的是創建一個有效的監控體系,畢竟靠用戶反饋仍是不可靠也是滯後的。相信Flutter的將來必定是光明的!