flutter混合开发踩坑之旅

flutter混合开发运行报错:VM snapshot must be valid. /Check failed: vm. Must be able to initialize the VM.

在安卓原生项目里集成了flutter_module,按照官方的步骤流程走完再运行原生项目的时候,发现程序启动之后崩溃,报错日志如下:

[ERROR:flutter/runtime/dart_vm_data.cc(19)] VM snapshot invalid and could not be inferred from settings.
[ERROR:flutter/runtime/dart_vm.cc(241)] Could not setup VM data to bootstrap the VM from.
[ERROR:flutter/runtime/dart_vm_lifecycle.cc(89)] Could not create Dart VM instance.
[FATAL:flutter/shell/common/shell.cc(218)] Check failed: vm. Must be able to initialize the VM.

网上找了一下解决方案,大部分都是这种流程:

方案一:

1、 在flutter module的build文件的android节点添加:


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)
    }
}

2、 修改flutter_sdk目录下packages/flutter_tools/gradle/flutter.gradle:

change
variant.outputs[0].processResources.dependsOn(copyFlutterAssetsTask)
to
variant.outputs[0].processResources.dependsOn(flutterTask)

方案二:

github上有一个issues有一个回答,链接如下

https://github.com/flutter/flutter/issues/19818

这个哥们比较讨巧,他对比了一下apk,发现flutter_assets文件夹没有打包到assets目录下, 他说他也不知道为什么没有打包进去。他手工把flutter module编译出来的flutter_assets的拷贝到安卓项目中,然后重新编译打包,就没有问题了,这种方式治标不治本,debug模式下这样是没问题了,但是打成release包又奔溃,得编译release版本的module文件,然后把编译出来的flutter_assets拷贝到安卓release包中才行

方案三:

1.在AS中打开flutter项目
2.命令行执行:flutter clean
3.cd .android
4…/gradlew clean
5…/gradlew assembleDebug
6.回到Android项目中运行APP(不需要 sync 或 rebuild)

找到$flutterRoot/packages/flutter_tools/gradle/flutter.gradle,搜索copyFlutterAssets。
可以找到有个copyFlutterAssetsTask,就是它没有被执行,看下gradle里是怎么写的。

根据打印日志发现走的是上面的if分支,通过代码可以看出:
gradle根据mainModuleName去找mergeAssets,如果Android项目没有配置project.rootProject.ext.mainModuleName,就会默认用"app"这个名字去找mergeAssets,r如果app module的名字不是"app",也没有配置project.rootProject.ext.mainModuleName,就找不到mergeAssets,mergeAssets为null,就没有去执行copyFlutterAssets

终极解决方案:在settings.gradle文件中加上mainModuleName的配置

setBinding(new Binding([gradle: this, mainModuleName: '主module名称']))
evaluate(new File(
        settingsDir.parentFile,
        'my_flutter/.android/include_flutter.groovy'
))

参考:https://blog.csdn.net/l707941510/article/details/98513208
方案三中的flutter.gradle文件在SDK1.7.8版本中还是这个逻辑,但是在最新的SDK(1.9.1)中已经做了修改,逻辑已经改变,是否已经修复该问题我还未验证,大家可以试一下

我采用了第三种方案,,产生这个的原因主要是由于不同模式下的产物没有清理使用了缓存,删除掉所有build文件的内容再全量编译一次,先在flutter module所在的项目跑一遍(包含.android的项目),然后运行宿主所在的项目,,,发现问题就解决了。。

flutter finished with non-zero exit value 1

这个问题的出现方式是,项目引用着某个flutter_module,然后换成另一个flutter_modlue,同步一下文件,发现报这个错,解决方式很简单,把主项目的build文件删除,然后clean build就行了

a globalkey was used multiple times inside one widget’s child list

这个问题出现的情况是第一次集成某个flutter_module,然后从原生入口点击进入flutter页面,然后模拟器界面出现了这个提示,找了好久并没有发现合适的方案,遇见这个问题的人也不多,,最后我跑了一下flutter_module,再回来跑主项目,就可以了。。好坑。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章