Flutter接入現有Android工程踩坑之旅

把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

armeabi支持

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路徑下:架構

  • android-arm
  • android-arm-dynamic-profile
  • android-arm-dynamic-release
  • android-arm-profile
  • android-arm-release

能夠經過以下腳本實現: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就能同時支持兩種架構。

打包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的崩潰問題

在第一次配置好工程或者切換mode的過程當中,可能會遇到如下的崩潰問題:

Check failed: vm. Must be able to initialize the VM.

主要是因爲不一樣模式下的產物沒有清理使用了緩存,解決辦法是刪除掉全部build文件的內容再全量編譯一次就能夠了。

總結

這是我在作flutter工程配置中遇到的一些坑,文風偏流水帳,請你們見諒,只但願能對你們有一些借鑑意義。另外,咱們已經在項目的兩個模塊中使用了flutter,開發效率確實能有很大提升,畢竟兩端只須要一我的開發就ok,並且UI小姐姐要求的頁面效果都能徹徹底底的完成,上線以後目前還沒發現什麼問題。下一步須要作的是創建一個有效的監控體系,畢竟靠用戶反饋仍是不可靠也是滯後的。相信Flutter的將來必定是光明的!

相關文章
相關標籤/搜索