背景
Flutter 作为谷歌下一代主推的全平台 UI 框架, 具有很多的优点:
支持全平台, 包括 Android,iOS,web 甚至桌面端.
全平台都基于同一套代码库, 区别于 React Native 的 learn once, write everywhere.
媲美原生的性能.
牛逼的开发效率, 这个深有体会, 目前笔者公司负责的一个电商 App, 随便修改一行代码 build 一次在 2018 款 MacBook pro 15 下都需要 4 分钟左右, Flutter 可以做到不到一秒.
丰富的组件库, 比 Android 的组件更加丰富.
国内已经有很多大厂已经有使用 Flutter 在他们的核心项目中了, 比如阿里的咸鱼, 腾讯的 now 直播, 京东商城等等.
今年整个互联网寒冬, 很多公司都在裁员, 移动端跨平台方案能够一定程度上节约开发成本, 而且 Android iOS 都是一套代码, 也避免了分端开发导致两端逻辑可能不一致的问题.
尝鲜
按照官方文档的指引 https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps, 很快我就完成了集成, 但是一运行, 进入 flutter 页面时, 总是黑屏过段时间就闪退了, 查看崩溃信息时发现应该是 flutter so 库没有打包进去, 这个问题是因为我们的项目是只打包 armeabi 单 abi. 而 flutter 只提供 armeabi-v7a 以上的 so. 所以我们把 abi 改成 armeabi-v7a 就可以顺利打包 flutter 的 so 库了, 如下:
- splits {
- abi {
- enable !project.hasProperty('runx86')
- reset()
- include 'armeabi-v7a'
- universalApk false
- }
- }
满心欢喜的赶紧 build 再次运行, 结果还是一样, 进入 flutter 页面, 还是黑屏一下, 然后闪退, 这时候出现的 error log 是:
- VM snapshot must be valid.
- Check failed: vm. Must be able to initialize the VM.
WTF:google 之, 发现一片非常有用的文章 https://github.com/flutter/flutter/issues/19818. 在这篇文章中提到:
vmfailed
看起来是说打包的 apk 的 assets 中缺少了 flutter_assets,flutter_assets 里面是什么? 我猜他妈的肯定是 dart vm 还有 dart 的代码. 这个哥们也比较实在, 他说他也不知道为什么没有打包进去. 于是按照这个哥们的方法, 手工把 flutter module 编译出来的 flutter_assets 的拷贝到安卓项目中, 然后重新编译打包, 我手指微微颤抖的点开 flutter 页面, 我操, flutter 页面终于出来, 我第一次流下了幸福的眼泪. 但是幸福过后, 还是要思考, 我不能每次都手工拷贝吧, 写个脚本拷贝也行, 但是还是显得不太专业, 我想要的是直接在 IDE 上点 build 按钮就能生成一个完美的 apk 包.
接着继续查看上面这个 issue 19818(这个 number 还蛮吉利的), 有个兄弟说是如果你的项目中有用到 productFlavors 的话, 你的 flutter 项目也必须要配置相同的 productFlavors 才会自动把 flutter_assets 打包进去. 按照下面这个方式进行代码调整:
productFlavor
build 打包运行, f**k, 还是不行. flutter_assets 怎样都打包不进 apk 里面. 然后就是无尽的尝试, 终于发现有一个中国的兄弟遇到跟我类似的问题 https://www.jianshu.com/p/3a88d9b993cd.
fluttermaster
看起来是需要切到 flutter 的 master 分支上才可以, 目前我是在 stable 分支上, 那就切把, 赶紧执行 flutter channel master. 这个过程需要翻墙, 或者添加 flutter 中国镜像. 要不然会下载不成功. 切成功之后, 试了无数次, 还行不行. 怎么办, 我已经生无死恋..........................
在经过多次痛哭流涕之后, 我真想把电脑合上, 背起书包回家 (已经是深夜了), 但是作为一个对技术有狂热追求的我, 我不甘心就这样失败. 也许是上帝的安排, 冥冥之中我对比了下别的项目 module 名称都是 App 这样, 而我们的却是 vipshop. 我想再尝试一把, 不行的话, 那我就放弃了. 于是我把 vipshop 重命名为 App,build 运行. 查看下 apk 打包的内容.
done
flutter_assets 终于打包进去了. 进入 flutter 页面也没闪退了. 呜呜... 今晚终于可以安心睡个好觉了. 赶紧掏出手机叫好滴滴, 打卡下班回家....
总结
整体的曲折经历上面已经说了, 下面总结下具体的改动点, 假设你的主工程和 flutter module 位于:
主工程:/somepath/my_app
flutter module: /somepath/flutter_module
主要改动点有:
flutter 切到 master 分支, 执行 flutter channel master.
按照官方指引 https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps 进行集成.
确保你的主工程的主 module 名称是 App,/somepath/my_app/App.
如果你的项目使用了 abi splits, 确认 include 的是 armeabi-v7a.
- splits {
- abi {
- enable !project.hasProperty('runx86')
- reset()
- include 'armeabi-v7a'
- universalApk false
- }
- }
假设你的主项目配置了 dev productFlavor, 那么你需要修改 /somepath/flutter_module/.Android/Flutter/build.gradle, 增加 dev productFlavor 和 buildTypes.
productflavor
修改 flutter 项目 /somepath/flutter_module/.Android/App/build.gradle, 增加 dev productFlavor
productflavor
大功告成!!
来源: http://www.jianshu.com/p/d9cc2ff365c8