轉(zhuǎn)自 Q吹個(gè)大氣球Q
本文主要介紹Flutter相關(guān)的東西,包括Fuchsia、Dart、Flutter特性、安裝以及整體架構(gòu)等內(nèi)容。
簡(jiǎn)介
Flutter作為谷歌最近推出的跨平臺(tái)開發(fā)框架,一經(jīng)推出便吸引了不少注意。關(guān)于Flutter,目前我們知道它是一個(gè)跨平臺(tái)開發(fā)框架。但是它本身并不止于此,例如Fuchsia、Dart等,我們也都需要去了解。
Fuchsia
說到Flutter,絕對(duì)繞不開Fuchsia,這個(gè)是谷歌開發(fā)的一款全新的操作系統(tǒng),GitHub地址以及Google source主頁。Fuchsia內(nèi)核是Magenta Kernel,一個(gè)基于LittleKernel的項(xiàng)目。該系統(tǒng)與Android相比,無論是存儲(chǔ)器還是內(nèi)存之類的硬件要求都大幅降低,外界推論是一款面向物聯(lián)網(wǎng)的系統(tǒng)。筆者倒是沒有查到谷歌開發(fā)這款操作系統(tǒng)的目的,如果有知曉的,也煩請(qǐng)告知。
就像很多博客主說的那樣,如果只是取代Android,那無疑是一種很不好的做法。任何技術(shù)的推動(dòng),都得靠背后的商業(yè)驅(qū)動(dòng),尤其是這種涉及到手機(jī)廠商利益的技術(shù)。
Flutter
Flutter是Fuchsia的開發(fā)框架,是一套移動(dòng)UI框架,可以快速在iOS、Android以及Fuchsia上構(gòu)建高質(zhì)量的原生用戶界面。 目前Flutter是完全免費(fèi)、開源的,GitHub地址。其官方編程語言為Dart,也是一門全新的語言。所以說,上手成本比較高,對(duì)于移動(dòng)端開發(fā)人員,語言以及框架都是全新的,整個(gè)技術(shù)棧的積累也都得從頭開始。
可以看下其官方介紹的特性:
- 快速開發(fā):Flutter的熱重載可以快速地進(jìn)行測(cè)試、構(gòu)建UI、添加功能并更快地修復(fù)錯(cuò)誤。
- 富有表現(xiàn)力,漂亮的用戶界面:自帶的Material Design和Cupertino(iOS風(fēng)格)widget、豐富的motion API、平滑而自然的滑動(dòng)效果。
- 響應(yīng)式框架:使用Flutter的現(xiàn)代、響應(yīng)式框架,和一系列基礎(chǔ)widget,輕松構(gòu)建您的用戶界面。
- 訪問本地功能和SDK:Flutter可以復(fù)用現(xiàn)有的Java、Swift或ObjC代碼,訪問iOS和Android上的原生系統(tǒng)功能和系統(tǒng)SDK。
- 統(tǒng)一的應(yīng)用開發(fā)體驗(yàn):Flutter擁有豐富的工具和庫,可以幫助開發(fā)者輕松地同時(shí)在iOS和Android系統(tǒng)中實(shí)現(xiàn)想法和創(chuàng)意。
- 原生性能:Flutter包含了許多核心的widget,如滾動(dòng)、導(dǎo)航、圖標(biāo)和字體等,這些都可以在iOS和Android上達(dá)到原生應(yīng)用一樣的性能。
其實(shí)從官方特性來看,唯一有點(diǎn)吸引力的就是統(tǒng)一的應(yīng)用開發(fā)體驗(yàn)。一套代碼運(yùn)行在多個(gè)平臺(tái),做到真正的跨平臺(tái)。像熱加載,目前Android開發(fā)本身就支持了,響應(yīng)式框架以及訪問本地功能和SDK,對(duì)于Native來說,本身并沒有多大的吸引。至于漂亮的用戶界面,國(guó)內(nèi)的商業(yè)項(xiàng)目,哪一個(gè)會(huì)去按照Material Design去設(shè)計(jì)。
跨平臺(tái)本身,往往意味著性能受損,通用性解決不了的問題,又得回到Native去實(shí)現(xiàn)。所以這些因素也是跨平臺(tái)從移動(dòng)端誕生之初就開始提,到現(xiàn)在也沒有被很好解決的一個(gè)原因。至于谷歌能夠做到什么程度,或者說開發(fā)者該保持什么期許,我覺得都不好說,或許谷歌解決了一個(gè)多年的難題,或者又像被谷歌放棄掉的其他項(xiàng)目一樣。拋開商業(yè)層面,對(duì)于技術(shù)人員,我們更多的是應(yīng)該去關(guān)注它的思想,谷歌是如何去解決這些實(shí)際存在很久的問題的,至于技術(shù)本身的發(fā)展,這個(gè)是個(gè)人開發(fā)者無法去左右的,技術(shù)的更迭,保持一種學(xué)習(xí)的狀態(tài),然后努力鍛煉身體,就能夠保證不被淘汰掉。
Dart
Dart是谷歌開發(fā)的計(jì)算機(jī)編程語言,于2011年10月份發(fā)布,可以被用于web、服務(wù)器、移動(dòng)端和物聯(lián)網(wǎng)等領(lǐng)域的開發(fā)。Flutter采用Dart,原因很多,拋開商業(yè)層面的Java版權(quán)問題,單純從技術(shù)層面:
- Dart是AOT(Ahead Of Time)編譯的,編譯成快速、可預(yù)測(cè)的本地代碼,使Flutter幾乎都可以使用Dart編寫;
- Dart也可以JIT(Just In Time)編譯,開發(fā)周期快;
- Dart可以更輕松地創(chuàng)建以60fps運(yùn)行的流暢動(dòng)畫和轉(zhuǎn)場(chǎng);
- Dart使Flutter不需要單獨(dú)的聲明式布局語言;
- Dart容易學(xué)習(xí),具有靜態(tài)和動(dòng)態(tài)語言用戶都熟悉的特性。
Dart最初設(shè)計(jì)是為了取代JavaScript成為web開發(fā)的首選語言,最后的結(jié)果可想而知,到Dart 2的發(fā)布,專注于改善構(gòu)建客戶端應(yīng)用程序的體驗(yàn),可以看出定位的轉(zhuǎn)變。用過Java、Kotlin的人,可以很快的上手Dart。
一門語言的成敗,拋開背后的商業(yè)推動(dòng),我想很重要的一點(diǎn)在于其生態(tài),生態(tài)的好壞,主要包括開發(fā)者以及第三方庫的數(shù)目,目前看,Dart的生態(tài)還是比較差。對(duì)于個(gè)人開發(fā)者,可以根據(jù)心情來選擇,但是對(duì)于商業(yè)應(yīng)用,有更復(fù)雜的考量標(biāo)準(zhǔn)。Dart背后有谷歌的推動(dòng),能發(fā)展到什么程度,還得看其商業(yè)運(yùn)作能力了。
配置
此部分針對(duì)Mac平臺(tái),Windows平臺(tái)的安裝配置,Linux平臺(tái)的安裝配置。由于筆者主要做移動(dòng)端開發(fā),如果想使用Flutter進(jìn)行iOS和Android全平臺(tái)的開發(fā),環(huán)境也建議是Mac平臺(tái),畢竟iOS只能在Mac下進(jìn)行模擬調(diào)試。
安裝Flutter
git clone -b beta https://github.com/flutter/flutter.git
export PUB_HOSTED_URL=https://pub.flutter-io.cn //國(guó)內(nèi)用戶需要設(shè)置
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn //國(guó)內(nèi)用戶需要設(shè)置
export PATH=`pwd`/flutter/bin:$PATH
iOS設(shè)置
brew update
brew install --HEAD libimobiledevice
brew install ideviceinstaller ios-deploy cocoapods
pod setup
Android設(shè)置
下載Android Studio,安裝Flutter插件,會(huì)將Dart插件也一起安裝。
體驗(yàn)Flutter
IDE建議選擇Android Studio,安裝了Flutter插件后,F(xiàn)lutter的開發(fā)跟Android
開發(fā)類似,附帶三種模版工程、斷點(diǎn)調(diào)試等。
在Android Studio里面新建一個(gè)Flutter Application的項(xiàng)目,選擇模擬器或者直接連接真機(jī)運(yùn)行,就可以看到一個(gè)簡(jiǎn)單的Flutter應(yīng)用了,可以在Android和iOS不同平臺(tái)下看看差異。
Flutter架構(gòu)
Flutter是一款移動(dòng)應(yīng)用程序SDK,一份代碼可以同時(shí)生成iOS和Android兩個(gè)高性能、高保真的應(yīng)用程序。
Flutter對(duì)于移動(dòng)開發(fā)人員,最誘惑的能力是其完全的跨平臺(tái)特性,不同于RN這種一處學(xué)到處寫,它是一處寫到出跑,但是他跟其他的跨平臺(tái)有何區(qū)別呢?
跨平臺(tái)解決方案
市面上的跨平臺(tái)解決方案,可以大致歸結(jié)為兩類:
- 使用平臺(tái)支持的web技術(shù):這些解決方案基本上加載了應(yīng)用程序中的移動(dòng)瀏覽器,并在該瀏覽器中執(zhí)行所有的邏輯,例如PhoneGap。
- 本地跨平臺(tái):程序員編寫的代碼自動(dòng)轉(zhuǎn)換為Native代碼,這種方式的優(yōu)點(diǎn)是近乎原生的性能,例如RN、Weex、Xamarin等。
這些方案是否真正的解決了跨平臺(tái)問題呢?從目前的狀況來看,很顯然是沒有的,因?yàn)樗鼈兌际冀K逃不開性能、包大小、流暢性、內(nèi)存、平臺(tái)特性等問題。
RN單獨(dú)擰出來說,是因?yàn)樗鼈儾⒉皇亲非蟮囊淮螌懙教幣埽現(xiàn)B自己也知道不現(xiàn)實(shí),所以把口號(hào)改成一次學(xué)到處寫,去考慮平臺(tái)的特性,去考慮這個(gè)被跨平臺(tái)方案經(jīng)常忽略的問題。但是RN也并沒有被廣泛的接納,從阿里開始使用到放棄,里面的很多坑都繞不過去。寫一次到處跑確實(shí)很誘人,從企業(yè)角度講,可以節(jié)省大量的人力,但是卻忽略了一個(gè)很基礎(chǔ)的問題,不同平臺(tái)是否希望如此,蘋果是否會(huì)愿意自己的生態(tài)被打破,不同平臺(tái)的特性是否應(yīng)該被歸為一致。
Flutter的跨平臺(tái)解決方案
上面簡(jiǎn)單說了傳統(tǒng)跨平臺(tái)解決方案,我們?cè)倩剡^頭看看Flutter的解決方案,F(xiàn)lutter跨平臺(tái)最核心的部分,是它的高性能渲染引擎(Flutter Engine)。Flutter不使用瀏覽器技術(shù),也不使用Native的原生控件,它使用自己的渲染引擎來繪制widget。
說到widget,就要說一句Flutter的一切皆為widget
理念。widget是Flutter應(yīng)用程序用戶界面的基本構(gòu)建塊。每個(gè)widget都是用戶界面一部分的不可變聲明。與其他將視圖、控制器、布局和其他屬性分離的框架不同,F(xiàn)lutter具有一致的統(tǒng)一對(duì)象模型:widget。在更新widget的時(shí)候,框架能夠更加的高效。
對(duì)于Android平臺(tái),F(xiàn)lutter引擎的C/C++代碼是由NDK編譯,在iOS平臺(tái),則是由LLVM編譯,兩個(gè)平臺(tái)的Dart代碼都是AOT編譯為本地代碼,F(xiàn)lutter應(yīng)用程序使用本機(jī)指令集運(yùn)行。
Flutter正是是通過使用相同的渲染器、框架和一組widget,來同時(shí)構(gòu)建iOS和Android應(yīng)用,而無需維護(hù)兩套獨(dú)立的代碼庫。
Flutter將UI組件和渲染器從平臺(tái)移動(dòng)到應(yīng)用程序中,這使得它們可以自定義和可擴(kuò)展。Flutter唯一要求系統(tǒng)提供的是canvas,以便定制的UI組件可以出現(xiàn)在設(shè)備的屏幕上。
Flutter框架
Flutter框架是一個(gè)分層的結(jié)構(gòu),每個(gè)層都建立在前一層之上。
框架沒什么可介紹的(主要是詳細(xì)介紹我也沒找到啥資料,大寫的尷尬),看著很簡(jiǎn)單,就分為兩個(gè)部分,F(xiàn)ramework和Engine部分,其中Framework提供了各種基礎(chǔ)的組件庫,Engine部分渲染各種widget,兩者共同作用,使得運(yùn)行性能高效穩(wěn)定。
Flutter調(diào)研
生態(tài)
在Flutter官方的Pub平臺(tái)上,純Flutter Package大概有兩千多個(gè),基本上常見的庫還是都有的,例如網(wǎng)絡(luò)、圖片、音視頻播放等等。但是對(duì)于目前Android以及iOS的生態(tài),還是遠(yuǎn)遠(yuǎn)的不足的,對(duì)于一些復(fù)雜的UI或者一些不是特別通用的功能,就得自己去實(shí)現(xiàn)。
包大小
根據(jù)官網(wǎng)的介紹,一個(gè)最小的Android版本的Flutter應(yīng)用。release版本大小約6.7MB,其中核心引擎大約3.3MB,框架+應(yīng)用程序代碼大約是1.25MB,LICENSE文件(包含在app.flx中)是55k,必需的Java代碼.dex為40k,并且約有2.1MB的ICU數(shù)據(jù)。考慮到目前網(wǎng)絡(luò)環(huán)境,包大小的增加,還也在可以接受的范圍。
Crash
iOS運(yùn)行官方的例子,會(huì)有時(shí)候crash掉,因此我們將一個(gè)開源的Flutter應(yīng)用,添加了Bugly上報(bào),在Android平臺(tái)進(jìn)行了眾測(cè)。
參與人次大概150人左右,啟動(dòng)次數(shù)大概500次左右,沒有出現(xiàn)一次Crash數(shù)據(jù)上報(bào),由于app很簡(jiǎn)單,并不能說明很多問題,但是眾測(cè)用戶反饋了約12條信息,其中1條是類似于ANR,無法操作,其余的部分則是卡頓相關(guān)的反饋。
流暢性
將官方的例子發(fā)給測(cè)試同學(xué),讓在iOS以及Android平臺(tái)的不同機(jī)子上運(yùn)行了下。在iOS上基本上流暢運(yùn)行,沒有出現(xiàn)卡頓的現(xiàn)象,在Android部分設(shè)備上,出現(xiàn)了卡頓的現(xiàn)象。
由于沒有復(fù)雜的例子,其實(shí)這個(gè)流暢性的測(cè)試,意義不是特別大,官方簡(jiǎn)單的控件展示demo程序,本身就很簡(jiǎn)單,但是在Android上還是出現(xiàn)了不少問題,只能說明整體還有非常大的優(yōu)化空間。
編寫復(fù)雜程度
試著照著一張?jiān)O(shè)計(jì)稿進(jìn)行了簡(jiǎn)單的純布局代碼工作,初次接觸用起來還是比較復(fù)雜,尤其是那恐怖的嵌套層級(jí),對(duì)代碼維護(hù)來說絕對(duì)是個(gè)問題,而且由于Flutter的widget機(jī)制,很多組件只支持最基本的操作,例如一些擴(kuò)展的屬性,都得自己去實(shí)現(xiàn),況且現(xiàn)在組件庫還不是非常的豐富。代碼量也比較多,整個(gè)代碼大概有500行左右,還只是不涉及到一些交互以及數(shù)據(jù)綁定等。
從運(yùn)行效果看,還是比較的不錯(cuò),兩者還原的效果都挺不錯(cuò)的。
結(jié)論
如果是個(gè)人而言,我覺得可以放心大膽的去學(xué)習(xí)嘗試,如果自己開發(fā)app的話,可以寫一套代碼,在多個(gè)平臺(tái)運(yùn)行發(fā)布。
如果是商業(yè)團(tuán)隊(duì),這個(gè)就要自行取舍,目前而言,F(xiàn)lutter生態(tài)還是非常的不完善,相關(guān)的資料也非常少。目前處于beta 3階段,多久能到release,能否到release,都是個(gè)未知數(shù),而且,用Flutter,最大的風(fēng)險(xiǎn),就是項(xiàng)目整體的不可把控,一旦出現(xiàn)一些坑,如果能填好,那還行,如果涉及到無法解決的問題,就只能放棄。因此看自己團(tuán)隊(duì)人力以及時(shí)間合理安排比較合適。目前看阿里的咸魚團(tuán)隊(duì)在研究Flutter。
如果單純從Flutter本身能夠解決的問題的方面出發(fā),使用Flutter確實(shí)能夠產(chǎn)生一定的收益,節(jié)省開發(fā)成本,如果考慮到目前坑比較多的狀況,加上踩坑的時(shí)間,可能就無法去評(píng)估了。
總體來說,F(xiàn)lutter確實(shí)是一個(gè)比較不錯(cuò)的東西,如果谷歌能夠把它發(fā)展的比較完善,對(duì)于個(gè)人以及小團(tuán)隊(duì)來說,確實(shí)是個(gè)福音。