跨平台开发实践之Flutter
跨平臺(tái)開發(fā)實(shí)踐之Flutter
先說點(diǎn)廢話。今天的主題關(guān)于跨平臺(tái)開發(fā)技術(shù)的。跨平臺(tái)開發(fā)大家應(yīng)該都了解,無非就是寫一套代碼可以運(yùn)行在兩個(gè)甚至多個(gè)平臺(tái)之上,而對(duì)于我們客戶端/前端開發(fā)來說,跨平臺(tái)一般就是跨現(xiàn)在主流的Android和iOS兩個(gè)移動(dòng)端平臺(tái),再牛逼一點(diǎn)的可以加上Web瀏覽器。
目前業(yè)內(nèi)也有很多跨平臺(tái)解決方案,例如Hybird、ReactNative、微信小程序、阿里的Weex、微軟的Cordova、Xamarin等。其中一些方案甚至被叫囂要取代原生開發(fā),當(dāng)然目前看來是不可能的。因?yàn)楸M管前面說的幾種跨平臺(tái)方案可以做到多端復(fù)用,動(dòng)態(tài)更新,但是都避不開老生常談的問題,就是在高要求下的加載渲染效率和復(fù)雜動(dòng)畫交互的實(shí)現(xiàn),它們做的都不如原生應(yīng)用。
然后再說今天和大家分享一個(gè)開發(fā)框架Flutter,它與其他跨平臺(tái)方案都不同,一統(tǒng)天下可能很難,但是我覺得是目前最優(yōu)的跨平臺(tái)解決方案。
Flutter是什么
官方定義:
Flutter是Google發(fā)布的一款UI開發(fā)工具集,開發(fā)語言是Dart。用它可以為移動(dòng)端、web瀏覽器、PC桌面構(gòu)建漂亮的,本機(jī)編譯的應(yīng)用程序,關(guān)鍵是用的同一套代碼。
在這里大家比較關(guān)注的點(diǎn),應(yīng)該是一套代碼可以運(yùn)行在不同的平臺(tái)上。官方說明的手機(jī)平臺(tái)只包含了Android和iOS系統(tǒng),等后面大家了解完Flutter跨平臺(tái)原理后就會(huì)發(fā)現(xiàn),Flutter構(gòu)建的應(yīng)用應(yīng)該可以運(yùn)行在其他移動(dòng)操作系統(tǒng)上,例如阿里的云OS,甚至是華為新推出的鴻蒙系統(tǒng),甚至是Web和PC平臺(tái)上。
由于Web瀏覽器的特殊性(因?yàn)閃eb應(yīng)用只能訪問瀏覽器提供的API,而無法直接訪問系統(tǒng)API),所以Flutter在Web瀏覽器上運(yùn)行的機(jī)制和其他平臺(tái)不一樣,這里先簡(jiǎn)單說一下。
我們都知道,在瀏覽器運(yùn)行的web頁面必須符合三大標(biāo)準(zhǔn),即HTML、CSS和JavaScript,通過這三劍客來實(shí)現(xiàn)頁面呈現(xiàn)和業(yè)務(wù)邏輯處理,其他的東西瀏覽器是不承認(rèn)的。
大家看一下這張圖,Framework層就用Dart編寫的,面向開發(fā)者的API,可以實(shí)現(xiàn)業(yè)務(wù)布局和業(yè)務(wù)邏輯,這一部分在不同的平臺(tái)上是一樣的。主要是看下面的dart:ui部分是如何實(shí)現(xiàn)。Flutter Web Engine是Flutter開發(fā)團(tuán)隊(duì)自己實(shí)現(xiàn)的一個(gè)Web引擎,簡(jiǎn)單來說就是把Dart編寫的頁面轉(zhuǎn)換成瀏覽器認(rèn)識(shí)的HTML、CSS和JavaScript。當(dāng)然,這個(gè)轉(zhuǎn)換過程并不是一對(duì)一映射((完整說明見https://medium.com/flutter/hummingbird-building-flutter-for-the-web-e687c2a023a8)),而是根據(jù)不同的內(nèi)容選擇不同的圖片實(shí)現(xiàn)(HTML + CSS + Canvas )。
Dart Code -> JS -> HTML + CSS + Canvas -> 瀏覽器渲染
Flutter特性:
- 高性能 媲美原生應(yīng)用的界面渲染性能-60fps,但是Flutter的目標(biāo)遠(yuǎn)不止如此。Flutter在發(fā)布之初號(hào)稱可以達(dá)到120fps,這是可以達(dá)到游戲甚至VR應(yīng)用的渲染效率的要求的。不過我們不能只聽Google的一面之詞,要自己親測(cè)之后才踏實(shí)。不過到目前為止我還沒有自己上手來對(duì)原生和Flutter的效率作對(duì)比。不過我們可以先參考一下其他公司的測(cè)試結(jié)果。2018年8月,美團(tuán)用Flutter寫一個(gè)全品類頁面,在使用過程中根本察覺不出來區(qū)別,經(jīng)過數(shù)據(jù)統(tǒng)計(jì),渲染10000幀過程中,Android原生平均耗時(shí)10.21ms,Flutter平均耗時(shí)12.28ms。這是在沒有對(duì)Flutter的頁面做任何過度繪制、緩存優(yōu)化的前提下的測(cè)試結(jié)果。
- 漂亮的UI Flutter允許開發(fā)者控制屏幕上的每一個(gè)像素,從而達(dá)到在不同平臺(tái)上擁有高度一致的外觀表現(xiàn),同時(shí)內(nèi)置了Material和Cupertino風(fēng)格的UI組件。
- 快速開發(fā) 相對(duì)于原生應(yīng)用的耗時(shí)開發(fā)流程(編輯、編譯、安裝、啟動(dòng)、顯示),Flutter支持了在Web開發(fā)過程中才能體驗(yàn)到的熱重載功能(編譯、顯示)
- 開源 Flutter是一個(gè)基于BSD-style的開源項(xiàng)目,任何開發(fā)者都可以獲取源碼或貢獻(xiàn)自己的代碼。
歷史和現(xiàn)狀:
2014.10 Flutter的前身Sky在Github上開源
2015.10 經(jīng)過一年的開源,Sky正式改名為Flutter。在Dart開發(fā)者峰會(huì)上發(fā)布了第一個(gè)版本。
2018.02 在世界移動(dòng)大會(huì)(MWC)發(fā)布首個(gè)Beta版
2018.06 在(GMTC)發(fā)布首個(gè)預(yù)覽版
2018.12 在Flutter Live2018上發(fā)布1.0穩(wěn)定版。
變更:
全新iOS風(fēng)格的widget
接入約20種Firebase服務(wù)
使用Dart 2.1,生成更小的代碼和更快的速度
2019.02 在世界移動(dòng)大會(huì)(MWC)發(fā)布1.2
變更:
提升框架性能和質(zhì)量
視頻播放、WebView、Maps等bug修復(fù)
支持Android App Bundle
基于Web的編程工具套件
支持前端開發(fā)者使用HTML和CSS語法編寫應(yīng)用
2019.05 在Google IO大會(huì)上發(fā)布1.7,也是目前最新版本。
變更:
支持Android X
支持32位和64位的Android App Bundle和Apk
更新小部件RangeSlider以及更復(fù)雜的排版
支持游戲控制器
趨勢(shì):
[外鏈圖片轉(zhuǎn)存失敗(img-vE5IEYDG-1566562914259)(media/15454717435900/3465086455-5d0cafa0245c7_articlex.jpeg)]
從Github上的Star數(shù)來看,在Google剛推出Flutter時(shí)發(fā)展很緩慢,直到18年2月發(fā)布首個(gè)Beta版本后迎來了爆發(fā)性增長(zhǎng),12月發(fā)布第一個(gè)正式后增長(zhǎng)更快。目前在Github上,Flutter項(xiàng)目的Star數(shù)為72895,要知道Facebook的react-native的Star數(shù)為80113.
由于Flutter的諸多優(yōu)勢(shì),我們熟悉的很多大廠都開始應(yīng)用Flutter到自家的產(chǎn)品中。
例如Google旗下的Google Ads、阿里旗下的閑魚、騰訊旗下的NOW直播、頭條的抖音等等。還有我司現(xiàn)在正在接入的Square公司的刷卡功能,Square都已經(jīng)提供了Flutter版本的SDK。
盡管許多大廠開始將Flutter應(yīng)用到商業(yè)中,但并不代表Flutter已經(jīng)非常完美和穩(wěn)定了。比如一些非常關(guān)鍵的功能還仍處于預(yù)覽狀態(tài),包括將Flutter和原生的混合開發(fā);在Web瀏覽器中運(yùn)行Flutter應(yīng)用。
Flutter怎么來的
通過對(duì)Eric的訪談可以知道:
Eric Seidel是Flutter團(tuán)隊(duì)的頭頭。Eric之前是做Web開發(fā)的,在Chrome團(tuán)隊(duì)工作,并且很擅長(zhǎng)圖像渲染這一領(lǐng)域。在某段時(shí)間,他們遇到了一些問題,他們想讓W(xué)eb中的一部分能夠擁有更加平滑的體驗(yàn),于是他們做了一個(gè)試驗(yàn),考慮到不一定非要與Web兼容,于是開始刪代碼,刪除那些為了兼容舊的訪問方式的支持代碼,把Web開發(fā)中不常用的內(nèi)容全部刪除。最后對(duì)精簡(jiǎn)后代碼做了一次基準(zhǔn)測(cè)試,發(fā)現(xiàn)效率提高了20倍。
再之后研究就屬于Flutter項(xiàng)目的范疇了。
在2015年4月的Dart開發(fā)者會(huì)議上,Eric分享了Sky項(xiàng)目,也就是Flutter前身,并且現(xiàn)場(chǎng)用Android手機(jī)演示了用Dart寫的應(yīng)用程序,聲稱達(dá)到120fps的渲染效率。
Flutter框架結(jié)構(gòu)
Flutter框架的整體架構(gòu)也是分層的,貌似分層架構(gòu)是解決復(fù)雜項(xiàng)目實(shí)現(xiàn)的不二法則。看到這張圖讓我想到了Android系統(tǒng)的框架結(jié)構(gòu)、網(wǎng)絡(luò)協(xié)議棧的結(jié)構(gòu)、還有我們App的項(xiàng)目結(jié)構(gòu),呵呵。
Flutter整體氛圍三層:
1、框架層,由Dart編寫。
2、引擎層,由C/C++編寫。
3、平臺(tái)嵌入層,由平臺(tái)對(duì)應(yīng)語言實(shí)現(xiàn)。
通過這張架構(gòu)圖可以看出,Flutter中平臺(tái)相關(guān)的特性很少,所以當(dāng)宿主系統(tǒng)升級(jí)時(shí),Flutter不需要很多的適配開發(fā)工作。
框架層
Widgets是UI組件部分,其中Material和Cupertino是對(duì)Widgets的封裝,方便開發(fā)者實(shí)現(xiàn)不同的風(fēng)格的App,減少開發(fā)量。
框架層的Rendering和引擎中的Rendering模塊代表了Flutter對(duì)視圖樹的抽象、布局、繪制的邏輯,也就是說Flutter的UI框架的圖像渲染是自己做的,既不依賴WebView,也不委托給原生。
再往下的Animation、Painting、Gestures是Flutter提供的動(dòng)畫、繪圖、手勢(shì)處理的Api。
Foundation 是一些Dart語言提供的一些常用的庫,例如網(wǎng)絡(luò)和IO。
引擎層
Platform Channels + Native Plugins實(shí)現(xiàn)了Dart語言和原生語言的通信機(jī)制。
SystemEvents來處理系統(tǒng)事件,比如觸摸、鍵盤輸入、屏幕反轉(zhuǎn)等。
Service Protocol 擴(kuò)展服務(wù),例如性能檢測(cè)、應(yīng)用信息追蹤、調(diào)試
Composition 多個(gè)圖層合并,提交渲染效率
Dart VM Management,Dart虛擬機(jī)管理。
Frame Scheduling和Frame Pipelining負(fù)責(zé)幀圖像的調(diào)度和排序。
TextLayout則專門負(fù)責(zé)文字排版
嵌入層
因?yàn)镕lutter本身還是依附在一個(gè)原生的頁面上的,比如Android中的Activity、iOS中的ViewController。而且系統(tǒng)的Api訪問還是得通過原生環(huán)境橋接一下。
所以不可避免的會(huì)對(duì)不同平臺(tái)做對(duì)應(yīng)的適配。
Render Surface Setup,設(shè)置原生環(huán)境的渲染圖層,例如Android中的SurfaceView。
Packaging,打包成對(duì)應(yīng)平臺(tái)的安裝包時(shí),需要把上面兩層?xùn)|西一并打包。
Thread Setup,其實(shí)Flutter的運(yùn)行線程是由系統(tǒng)的線程策略實(shí)現(xiàn)的。
Event Loop Interoperability,事件循環(huán)操作
為什么選擇Dart
有很多說,沒有選擇JavaScript作為開發(fā)語言,會(huì)嚴(yán)重影響Flutter的推廣。畢竟JavaScript如此普遍,相對(duì)于新學(xué)一門語言,開發(fā)人員轉(zhuǎn)移到Flutter的學(xué)習(xí)成本會(huì)很低。
我們想到的,人家Flutter團(tuán)隊(duì)不可能想不到。那為什么Flutter還是選擇了Dart?想知道為什么,還得深挖一下Dart的歷史。
Dart歷史:
Dart是Google在2011推出了一款應(yīng)用Web開發(fā)的語言,它的團(tuán)隊(duì)由Chrome瀏覽器V8引擎團(tuán)隊(duì)的Lars Bak主持,它的推出目的是取代JavaScript做前端開發(fā),成為下一代結(jié)構(gòu)化Web開發(fā)語言。Dart提供兩種方式運(yùn)行:一是運(yùn)行在本地虛擬機(jī)上。二是將代碼轉(zhuǎn)換成JavaScript。
然而由于Node.js的火爆將JavaScript推到了前后端通吃的地位,Dart也就慢慢退出了開發(fā)者的視野,直到改變思路應(yīng)用于移動(dòng)端開發(fā)后,煥發(fā)了第二春。
那Flutter團(tuán)隊(duì)為什么沒有選擇開發(fā)者群體更多的JavaScript語音,或者使用C++語言來達(dá)到更簡(jiǎn)便的框架結(jié)構(gòu),因?yàn)橛肅++直接可以調(diào)用Skia,可以直接與原生代碼通信(不再需要Dart橋接到C/C++,C/C++再JNI橋接到Java)。
我覺得原因很簡(jiǎn)單:
跨平臺(tái)歷史及技術(shù)區(qū)別
純Web時(shí)代
Hybird(Html + JsBridge)Cordova
完全利用Web標(biāo)準(zhǔn),依賴WebView的渲染能力,完全能滿足產(chǎn)品或設(shè)計(jì)對(duì)頁面實(shí)現(xiàn)要求。
為了能訪問原生Api,需要原生配合開發(fā)一套橋接的接口,暴露出原生系統(tǒng)接口能力。
缺點(diǎn)也很明白,WebView是一個(gè)重量級(jí)組件,并且Html/Js/css的加載、解析、渲染過程非常耗時(shí)。
當(dāng)然我們可以做成離線方式,將Html頁面提前下載到本地,這樣會(huì)提高加載的速度。但是由于WebView對(duì)Html頁面的解析、渲染都是在一個(gè)線程中執(zhí)行的,對(duì)于復(fù)雜的交互和頁面動(dòng)畫實(shí)現(xiàn)上,效果差強(qiáng)人意。
泛Web時(shí)代
ReactNative Weex 小程序 快應(yīng)用
雖然還是使用JavaScript語言基于WebView開發(fā),但是自定義一套控件標(biāo)簽,并一一映射到原生控件,將頁面渲染委托給原生系統(tǒng),所以渲染速度上會(huì)優(yōu)于純Web方式。而且單獨(dú)使用js引擎自定義了js的解析,例如iOS的jscore、小程序用騰訊自己的X5瀏覽器內(nèi)核,快應(yīng)用用阿里的UC瀏覽器內(nèi)核。
映射到原生控件的方式顯示比WebView渲染能力高一些,所以這些方案在發(fā)布的時(shí)候就標(biāo)榜自己能達(dá)到原生應(yīng)用的用戶體驗(yàn)。但是這種方式有兩個(gè)缺點(diǎn):第一個(gè)還是構(gòu)建復(fù)雜交互時(shí)要依賴映射方案中提供的接口,如果不滿足還是要原生開發(fā)配合來一對(duì)一挖細(xì)節(jié)來實(shí)現(xiàn),甚至直接由原生頁面實(shí)現(xiàn)。第二個(gè)是系統(tǒng)升級(jí)后,會(huì)有新的原生組件出現(xiàn),或者舊的組件棄用,所以系統(tǒng)適配的難度較大。
方法包裝時(shí)代
Xamarin C#實(shí)現(xiàn)
自繪引擎時(shí)代
Flutter
基于高效的2D渲染引擎Skia,完全獨(dú)立的UI繪制渲染邏輯,不依賴WebView,也不依賴原生控件,能完全解決前面的跨平臺(tái)方案的最大短板。
當(dāng)然,如果需要訪問系統(tǒng)Api的話,還得額外需要插件開發(fā),將Dart與原生語言建立通信渠道。這是每個(gè)跨平臺(tái)方案都躲不過的一道坎,那么如果系統(tǒng)的UI開發(fā)框架就是Flutter呢?例如Fuchsia, 那就不需要插件開發(fā)了。
那么Flutter就沒有缺點(diǎn)了么?
1、安裝包體積過大。相對(duì)原生開發(fā)出來的安裝包,Flutter應(yīng)用安裝包大很多,一個(gè)Demo示例都要10M左右的體積。因?yàn)橐袴lutter運(yùn)行環(huán)境、Skia繪圖引擎、還有其他一些支持庫打包進(jìn)apk、ipa中。
2、不能動(dòng)態(tài)化部署,因?yàn)椴幌馢avaScript是解釋執(zhí)行的,在正式發(fā)布時(shí),Dart是完全編譯成機(jī)器碼的,并且不支持反射。
3、調(diào)用系統(tǒng)Api時(shí)需要額外的通信,所以調(diào)用效率肯定比原生差一些
4、目前的混合開發(fā)功能還處于預(yù)覽狀態(tài),如果需要混合開發(fā)需要自己搞一套機(jī)制(原生頁面與Flutter頁面棧管理、多個(gè)Flutter環(huán)境的資源使用問題)出來,閑魚團(tuán)隊(duì)已經(jīng)做了一些努力。
總結(jié)
我們通過Flutter可以構(gòu)建出媲美原生的跨平臺(tái)應(yīng)用,其基本原理就是重寫UI繪制邏輯,通過高效的2D繪制引擎Skia實(shí)現(xiàn)頁面的快速渲染。同時(shí)提供了開發(fā)友好的JIT模式,提高了開發(fā)效率。
總結(jié)
以上是生活随笔為你收集整理的跨平台开发实践之Flutter的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微服务架构和SOA的区别
- 下一篇: 苏州软件测试11k工资要什么水平,3个月