1.在Android Studio 上Android項目混編Flutter
按照官方文檔 https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps
創(chuàng)建一個Flutter module
打開Terminal 運行:flutter create -t module my_flutter
完成后 命令:cd my_flutter/.android
運行:gradlew flutter:assembleDebug
在自己的項目的settings.gradle中添加:
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'項目名/my_flutter/.android/include_flutter.groovy'
))
引用module:在app/build.gradle 里 implementation project(':flutter')
按文檔編寫好java代碼和dart代碼后篮幢,就可以嘗試運行了。
坑一:有debug就有release
所以我運行了gradlew flutter:assembleRelease生成了flutter-release.aar
文檔上并未說明弛秋。
坑二:運行崩潰
VM snapshot must be valid.
Check failed: vm. Must be able to initialize the VM.
網(wǎng)上的辦法http://www.reibang.com/p/9b96999fc385
但當(dāng)我在flutter module的build文件的android節(jié)點添加
project.android.libraryVariants.all { variant ->
def targetAssets = "${project.buildDir}/intermediates/flutter/${variant.name}"
def customSourceSet = variant.getSourceSets()[0]
if (customSourceSet instanceof com.android.build.gradle.internal.api.DefaultAndroidSourceSet) {
customSourceSet = (DefaultAndroidSourceSet)customSourceSet
customSourceSet.getAssets().srcDirs(targetAssets)
}
}
DefaultAndroidSourceSet無法編譯。所以我放棄了些己。
我修改了flutter_sdk目錄下packages/flutter_tools/gradle/flutter.gradle文件
找到
variant.outputs[0].processResources.dependsOn(copyFlutterAssetsTask)
修改成
variant.outputs[0].processResources.dependsOn(flutterTask)
我并不清楚這個修改是否起決定性作用(坑四發(fā)現(xiàn)此改動并沒有什么用)锄禽。
我最終是解壓了flutter-debug.aar 找到assets下的flutter_assets
把flutter_assets添加到項目的app/assets里
雖然flutter-release.aar下也有,但文件內(nèi)容不一樣
因為debug下的flutter_assets已經(jīng)解決了該運行崩潰的問題磺平,所以并未繼續(xù)探究魂仍。
坑三:簽名打包,運行崩潰褪秀。
[FATAL:flutter/shell/platform/android/library_loader.cc(24)] Check failed: result.
既然debug運行ok蓄诽,八成就是簽名文件的問題了。ProGuard Rules for app 添加:
-keep class io.flutter.facade.**{*;}
-keep class io.flutter.plug.**{*;}
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
坑四:更新 dart 代碼 無效
當(dāng)你覺得差不多可以玩起來的時候媒吗,你發(fā)現(xiàn)無論怎么build仑氛,你更改的dart內(nèi)容都無法出現(xiàn)在你的app上。
問題在哪闸英?不能動態(tài)更新锯岖?
這便是復(fù)制flutter_assets帶來的問題。(所以坑二的問題就不能這么解決了)
flutter build 的內(nèi)容怎么讓Android來運行呢甫何?
看flutter_assets里的這些文件
vm_snapshot_data出吹、vm_snapshot_instr、isolate_snapshot_data辙喂、isolate_snapshot_instr
當(dāng)flutter 程序更新時捶牢,復(fù)制flutter_assets的內(nèi)容也要重新替換才行,但這并未長久之計巍耗。
當(dāng)時嘗試刪除復(fù)制在app/assets下的flutter_assets秋麸,意外的發(fā)現(xiàn)可以正常運行了,但是簽名打包依然不行炬太。這讓想起了之前的flutter-release.aar灸蟆,在我重新生成flutter-release.aar后,簽名打包也ok了亲族。
文獻參考:http://www.reibang.com/p/5d916f61ff62
編譯原理:https://yq.aliyun.com/articles/607014
坑五:如何更新flutter-release.aar和flutter-debug.aar
在my_flutter 下 運行 flutter build apk 和 flutter run 就可以炒考。目前我是這樣處理的可缚。
坑六:當(dāng)你升級你的Flutter版本后,之前的項目運行崩潰時
[ERROR:flutter/runtime/dart_vm.cc(265)] VM snapshot must be valid.
Upgrade your copy of Flutter
運行flutter upgrade,再重新flutter run
坑七:如何保持Flutter Module 和Android原生項目 獨立斋枢。
我發(fā)現(xiàn)我一開始創(chuàng)建flutter module 時就錯了帘靡,應(yīng)該在app項目同級目錄創(chuàng)建,而非子級杏慰。
因為它們本身就是相互獨立的测柠!
所以setting.gradle還是如文檔說的一樣:
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'my_flutter_module/.android/include_flutter.groovy'
))
坑八:重新創(chuàng)建Flutter
將Flutter項目下面的android/ios目錄刪除然后用"flutter create ."即可重新創(chuàng)建。
坑九:Check failed: vm. Must be able to initialize the VM
這個編譯失敗的問題一直無法解決缘滥,網(wǎng)上的一堆回答轰胁,基本都是同樣一個出處。而且不一定有效朝扼。我自己反復(fù)倒騰赃阀,好像明白了些什么。
flutter 是一個獨立的項目擎颖,所以它單獨運行的時候會創(chuàng)建自己的VM榛斯,也就是它有它自己的編譯環(huán)境。會不會是flutter 構(gòu)建的編譯環(huán)境和主APP程序的編譯環(huán)境不一致呢搂捧?
在點開flutter項目的.android目錄驮俗,果然發(fā)現(xiàn)了差異。我的gradle 版本不一致允跑。
(為什么會出現(xiàn)不一致的情況王凑,還待探究)在手動更改一致后,重新編譯就ok了聋丝。