背景
Flutter作為谷歌下一代主推的全平臺(tái)UI框架,具有很多的優(yōu)點(diǎn):
- 支持全平臺(tái),包括Android、iOS、Web甚至桌面端。
- 全平臺(tái)都基于同一套代碼庫,區(qū)別于React Native的learn once, write everywhere。
- 媲美原生的性能。
- 牛逼的開發(fā)效率,這個(gè)深有體會(huì),目前筆者公司負(fù)責(zé)的一個(gè)電商app,隨便修改一行代碼build一次在2018款macbook pro 15下都需要4分鐘左右,F(xiàn)lutter可以做到不到一秒。
- 豐富的組件庫,比Android的組件更加豐富。
- 國內(nèi)已經(jīng)有很多大廠已經(jīng)有使用Flutter在他們的核心項(xiàng)目中了, 比如阿里的咸魚,騰訊的now直播,京東商城等等。
今年整個(gè)互聯(lián)網(wǎng)寒冬,很多公司都在裁員,移動(dòng)端跨平臺(tái)方案能夠一定程度上節(jié)約開發(fā)成本,而且android ios都是一套代碼,也避免了分端開發(fā)導(dǎo)致兩端邏輯可能不一致的問題。
嘗鮮
按照官方文檔的指引https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps,很快我就完成了集成,但是一運(yùn)行,進(jìn)入flutter頁面時(shí),總是黑屏過段時(shí)間就閃退了,查看崩潰信息時(shí)發(fā)現(xiàn)應(yīng)該是flutter so庫沒有打包進(jìn)去,這個(gè)問題是因?yàn)槲覀兊捻?xiàng)目是只打包armeabi單abi。而flutter只提供armeabi-v7a以上的so。所以我們把a(bǔ)bi改成armeabi-v7a就可以順利打包flutter的so庫了,如下:
splits {
abi {
enable !project.hasProperty('runx86')
reset()
include 'armeabi-v7a'
universalApk false
}
}
滿心歡喜的趕緊build再次運(yùn)行,結(jié)果還是一樣,進(jìn)入flutter頁面,還是黑屏一下,然后閃退,這時(shí)候出現(xiàn)的error log是:
VM snapshot must be valid.
Check failed: vm. Must be able to initialize the VM.
WTF:google之,發(fā)現(xiàn)一片非常有用的文章https://github.com/flutter/flutter/issues/19818。在這篇文章中提到:

看起來是說打包的apk的assets中缺少了flutter_assets,flutter_assets里面是什么?我猜他媽的肯定是dart vm還有dart的代碼。這個(gè)哥們也比較實(shí)在,他說他也不知道為什么沒有打包進(jìn)去。于是按照這個(gè)哥們的方法,手工把flutter module編譯出來的flutter_assets的拷貝到安卓項(xiàng)目中,然后重新編譯打包,我手指微微顫抖的點(diǎn)開flutter頁面,我操,flutter頁面終于出來,我第一次流下了幸福的眼淚。但是幸福過后,還是要思考,我不能每次都手工拷貝吧,寫個(gè)腳本拷貝也行,但是還是顯得不太專業(yè),我想要的是直接在IDE上點(diǎn)build按鈕就能生成一個(gè)完美的apk包。
接著繼續(xù)查看上面這個(gè)issue 19818(這個(gè)number還蠻吉利的),有個(gè)兄弟說是如果你的項(xiàng)目中有用到productFlavors的話,你的flutter項(xiàng)目也必須要配置相同的productFlavors才會(huì)自動(dòng)把flutter_assets打包進(jìn)去。按照下面這個(gè)方式進(jìn)行代碼調(diào)整:

build打包運(yùn)行,f**k,還是不行。flutter_assets怎樣都打包不進(jìn)apk里面。然后就是無盡的嘗試,終于發(fā)現(xiàn)有一個(gè)中國的兄弟遇到跟我類似的問題http://www.itdecent.cn/p/3a88d9b993cd。

看起來是需要切到flutter的master分支上才可以,目前我是在stable分支上,那就切把,趕緊執(zhí)行flutter channel master。這個(gè)過程需要翻墻,或者添加flutter中國鏡像。要不然會(huì)下載不成功。切成功之后,試了無數(shù)次,還行不行。怎么辦,我已經(jīng)生無死戀..........................
在經(jīng)過多次痛哭流涕之后,我真想把電腦合上,背起書包回家(已經(jīng)是深夜了),但是作為一個(gè)對(duì)技術(shù)有狂熱追求的我,我不甘心就這樣失敗。也許是上帝的安排,冥冥之中我對(duì)比了下別的項(xiàng)目module名稱都是app這樣,而我們的卻是vipshop。我想再嘗試一把,不行的話,那我就放棄了。 于是我把vipshop重命名為app,build運(yùn)行。查看下apk打包的內(nèi)容。

flutter_assets終于打包進(jìn)去了。 進(jìn)入flutter頁面也沒閃退了。嗚嗚... 今晚終于可以安心睡個(gè)好覺了。 趕緊掏出手機(jī)叫好滴滴,打卡下班回家....
總結(jié)
整體的曲折經(jīng)歷上面已經(jīng)說了,下面總結(jié)下具體的改動(dòng)點(diǎn),假設(shè)你的主工程和flutter module位于:
- 主工程:/somepath/my_app
- flutter module: /somepath/flutter_module
主要改動(dòng)點(diǎn)有:
- flutter切到master分支,執(zhí)行flutter channel master。
- 按照官方指引https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps進(jìn)行集成。
- 確保你的主工程的主module名稱是app,/somepath/my_app/app。
- 如果你的項(xiàng)目使用了abi splits,確認(rèn)include的是armeabi-v7a。
splits {
abi {
enable !project.hasProperty('runx86')
reset()
include 'armeabi-v7a'
universalApk false
}
}
-
假設(shè)你的主項(xiàng)目配置了dev productFlavor,那么你需要修改 /somepath/flutter_module/.android/Flutter/build.gradle,增加dev productFlavor和buildTypes。
productflavor -
修改flutter項(xiàng)目 /somepath/flutter_module/.android/app/build.gradle,增加dev productFlavor
productflavor
大功告成??!

