本節(jié)將主要介紹一下移動(dòng)開(kāi)發(fā)技術(shù)的進(jìn)化歷程,主要是想讓讀者知道Flutter技術(shù)出現(xiàn)的背景。筆者認(rèn)為,了解一門(mén)新技術(shù)出現(xiàn)的背景是非常重要的谎势,因?yàn)橹挥辛私庵笆鞘裁礃拥模拍芾斫鉃槭裁磿?huì)是現(xiàn)在這樣杨名。
1.原生開(kāi)發(fā)與跨平臺(tái)技術(shù)
原生開(kāi)發(fā)
原生應(yīng)用程序是指某一個(gè)移動(dòng)平臺(tái)(比如iOS或安卓)所特有的應(yīng)用脏榆,使用相應(yīng)平臺(tái)支持的開(kāi)發(fā)工具和語(yǔ)言,并直接調(diào)用系統(tǒng)提供的SDK API台谍。比如Android原生應(yīng)用就是指使用Java或Kotlin語(yǔ)言直接調(diào)用Android SDK開(kāi)發(fā)的應(yīng)用程序须喂;而iOS原生應(yīng)用就是指通過(guò)Objective-C或Swift語(yǔ)言直接調(diào)用iOS SDK開(kāi)發(fā)的應(yīng)用程序。原生開(kāi)發(fā)有以下主要優(yōu)勢(shì):
- 可訪問(wèn)平臺(tái)全部功能(GPS、攝像頭)坞生;
- 速度快仔役、性能高、可以實(shí)現(xiàn)復(fù)雜動(dòng)畫(huà)及繪制是己,整體用戶體驗(yàn)好又兵;
主要缺點(diǎn):
- 平臺(tái)特定,開(kāi)發(fā)成本高卒废;不同平臺(tái)必須維護(hù)不同代碼寒波,人力成本隨之變大;
- 內(nèi)容固定升熊,動(dòng)態(tài)化弱,大多數(shù)情況下绸栅,有新功能更新時(shí)只能發(fā)版级野;
在移動(dòng)互聯(lián)網(wǎng)發(fā)展初期,業(yè)務(wù)場(chǎng)景并不復(fù)雜粹胯,原生開(kāi)發(fā)還可以應(yīng)對(duì)產(chǎn)品需求迭代蓖柔。 但近幾年,隨著物聯(lián)網(wǎng)時(shí)代到來(lái)风纠、移動(dòng)互聯(lián)網(wǎng)高歌猛進(jìn)况鸣,日新月異,在很多業(yè)務(wù)場(chǎng)景中竹观,傳統(tǒng)的純?cè)_(kāi)發(fā)已經(jīng)不能滿足日益增長(zhǎng)的業(yè)務(wù)需求镐捧。主要表現(xiàn)在:
- 動(dòng)態(tài)化內(nèi)容需求增大;當(dāng)需求發(fā)生變化時(shí)臭增,純?cè)鷳?yīng)用需要通過(guò)版本升級(jí)來(lái)更新內(nèi)容懂酱,但應(yīng)用上架、審核是需要周期的誊抛,這對(duì)高速變化的互聯(lián)網(wǎng)時(shí)代來(lái)說(shuō)是很難接受的列牺,所以,對(duì)應(yīng)用動(dòng)態(tài)化(不發(fā)版也可以更新應(yīng)用內(nèi)容)的需求就變的迫在眉睫拗窃。
- 業(yè)務(wù)需求變化快瞎领,開(kāi)發(fā)成本變大;由于原生開(kāi)發(fā)一般都要維護(hù)Android随夸、iOS兩個(gè)開(kāi)發(fā)團(tuán)隊(duì)九默,版本迭代時(shí),無(wú)論人力成本逃魄,還是測(cè)試成本都會(huì)變大荤西。
總結(jié)一下,純?cè)_(kāi)發(fā)主要面臨動(dòng)態(tài)化和開(kāi)發(fā)成本兩個(gè)問(wèn)題,而針對(duì)這兩個(gè)問(wèn)題邪锌,誕生了一些跨平臺(tái)的動(dòng)態(tài)化框架勉躺。
跨平臺(tái)技術(shù)簡(jiǎn)介
針對(duì)原生開(kāi)發(fā)面臨問(wèn)題,人們一直都在努力尋找好的解決方案觅丰,而時(shí)至今日饵溅,已經(jīng)有很多跨平臺(tái)框架(注意,本書(shū)中所指的“跨平臺(tái)”若無(wú)特殊說(shuō)明妇萄,即特指Android和iOS兩個(gè)平臺(tái))蜕企,根據(jù)其原理,主要分為三類(lèi):
- H5+原生(Cordova冠句、Ionic轻掩、微信小程序)
- JavaScript開(kāi)發(fā)+原生渲染 (React Native、Weex懦底、快應(yīng)用)
- 自繪UI+原生(QT for mobile唇牧、Flutter)
在接下來(lái)的章節(jié)中我們逐個(gè)來(lái)看看這三類(lèi)框架的原理及優(yōu)缺點(diǎn)。
2. Hybrid技術(shù)簡(jiǎn)介
H5+原生混合開(kāi)發(fā)
這類(lèi)框架主要原理就是將APP的一部分需要?jiǎng)討B(tài)變動(dòng)的內(nèi)容通過(guò)H5來(lái)實(shí)現(xiàn)聚唐,通過(guò)原生的網(wǎng)頁(yè)加載控件WebView (Android)或WKWebView(iOS)來(lái)加載(以后若無(wú)特殊說(shuō)明丐重,我們用WebView來(lái)統(tǒng)一指代android和iOS中的網(wǎng)頁(yè)加載控件)。這樣以來(lái)杆查,H5部分是可以隨時(shí)改變而不用發(fā)版扮惦,動(dòng)態(tài)化需求能滿足;同時(shí)亲桦,由于h5代碼只需要一次開(kāi)發(fā)崖蜜,就能同時(shí)在Android和iOS兩個(gè)平臺(tái)運(yùn)行,這也可以減小開(kāi)發(fā)成本客峭,也就是說(shuō)纳猪,H5部分功能越多,開(kāi)發(fā)成本就越小桃笙。我們稱這種h5+原生的開(kāi)發(fā)模式為混合開(kāi)發(fā) 氏堤,采用混合模式開(kāi)發(fā)的APP我們稱之為混合應(yīng)用或Hybrid APP ,如果一個(gè)應(yīng)用的大多數(shù)功能都是H5實(shí)現(xiàn)的話搏明,我們稱其為Web APP 鼠锈。
目前混合開(kāi)發(fā)框架的典型代表有:Cordova、Ionic 和微信小程序星著,值得一提的是微信小程序目前是在webview中渲染的购笆,并非原生渲染,但將來(lái)有可能會(huì)采用原生渲染虚循。
混合開(kāi)發(fā)技術(shù)點(diǎn)
如之前所述同欠,原生開(kāi)發(fā)可以訪問(wèn)平臺(tái)所有功能样傍,而混合開(kāi)發(fā)中,H5代碼是運(yùn)行在WebView中铺遂,而WebView實(shí)質(zhì)上就是一個(gè)瀏覽器內(nèi)核衫哥,其JavaScript依然運(yùn)行在一個(gè)權(quán)限受限的沙箱中,所以對(duì)于大多數(shù)系統(tǒng)能力都沒(méi)有訪問(wèn)權(quán)限襟锐,如無(wú)法訪問(wèn)文件系統(tǒng)撤逢、不能使用藍(lán)牙等。所以粮坞,對(duì)于H5不能實(shí)現(xiàn)的功能蚊荣,都需要原生去做。而混合框架一般都會(huì)在原生代碼中預(yù)先實(shí)現(xiàn)一些訪問(wèn)系統(tǒng)能力的API莫杈, 然后暴露給WebView以供JavaScript調(diào)用互例,這樣一來(lái),WebView就成為了JavaScript與原生API之間通信的橋梁筝闹,主要負(fù)責(zé)JavaScript與原生之間傳遞調(diào)用消息敲霍,而消息的傳遞必須遵守一個(gè)標(biāo)準(zhǔn)的協(xié)議,它規(guī)定了消息的格式與含義丁存,我們把依賴于WebView的用于在JavaScript與原生之間通信并實(shí)現(xiàn)了某種消息傳輸協(xié)議的工具稱之為WebView JavaScript Bridge, 簡(jiǎn)稱 JsBridge,它也是混合開(kāi)發(fā)框架的核心柴我。
示例:JavaScript調(diào)用原生API獲取手機(jī)型號(hào)
下面我們以Android為例解寝,實(shí)現(xiàn)一個(gè)獲取手機(jī)型號(hào)的原生API供JavaScript調(diào)用。在這個(gè)示例中將展示JavaScript調(diào)用原生API的流程艘儒,讀者可以直觀的感受一下調(diào)用流程聋伦。我們選用筆者在Github上開(kāi)源的dsBridge作為JsBridge來(lái)進(jìn)行通信。dsBridge是一個(gè)支持同步調(diào)用的跨平臺(tái)的JsBridge界睁,此示例中只使用其同步調(diào)用功能觉增。
首先在原生中實(shí)現(xiàn)獲取手機(jī)型號(hào)的API getPhoneModel
class JSAPI {
@JavascriptInterface
public Object getPhoneModel(Object msg) {
return Build.MODEL;
}
}
將原生API通過(guò)WebView注冊(cè)到JsBridge中
import wendu.dsbridge.DWebView
...
//DWebView繼承自WebView,由dsBridge提供
DWebView dwebView = (DWebView) findViewById(R.id.dwebview);
//注冊(cè)原生API到JsBridge
dwebView.addJavascriptObject(new JsAPI(), null);
在JavaScript中調(diào)用原生API
var dsBridge = require("dsbridge")
//直接調(diào)用原生API `getPhoneModel`
var model = dsBridge.call("getPhoneModel");
//打印機(jī)型
console.log(model);
上面示例演示了JavaScript調(diào)用原生API的過(guò)程翻斟,同樣的逾礁,一般來(lái)說(shuō)優(yōu)秀的JsBridge也支持原生調(diào)用JavaScript,dsBridge也是支持的访惜,如果您感興趣嘹履,可以去github dsBridge項(xiàng)目主頁(yè)查看。
現(xiàn)在债热,我們回頭來(lái)看一下砾嫉,混合應(yīng)用無(wú)非就是在第一步中預(yù)先實(shí)現(xiàn)一系列API供JavaScript調(diào)用,讓JavaScript有訪問(wèn)系統(tǒng)的能力窒篱,看到這里焕刮,我相信你也可以自己實(shí)現(xiàn)一個(gè)混合開(kāi)發(fā)框架了舶沿。
總結(jié)
混合應(yīng)用的優(yōu)點(diǎn)是動(dòng)態(tài)內(nèi)容是H5,web技術(shù)棧配并,社區(qū)及資源豐富括荡,缺點(diǎn)是性能不好,對(duì)于復(fù)雜用戶界面或動(dòng)畫(huà)荐绝,WebView不堪重任一汽。
3. React Native、Weex及快應(yīng)用
本篇主要介紹一下 JavaScript開(kāi)發(fā)+原生渲染的跨平臺(tái)框架原理低滩。
React Native (簡(jiǎn)稱RN)是Facebook于2015年4月開(kāi)源的跨平臺(tái)移動(dòng)應(yīng)用開(kāi)發(fā)框架召夹,是Facebook早先開(kāi)源的JS框架 React 在原生移動(dòng)應(yīng)用平臺(tái)的衍生產(chǎn)物,目前支持iOS和Android兩個(gè)平臺(tái)恕沫。RN使用Javascript語(yǔ)言监憎,類(lèi)似于HTML的JSX,以及CSS來(lái)開(kāi)發(fā)移動(dòng)應(yīng)用婶溯,因此熟悉Web前端開(kāi)發(fā)的技術(shù)人員只需很少的學(xué)習(xí)就可以進(jìn)入移動(dòng)應(yīng)用開(kāi)發(fā)領(lǐng)域鲸阔。
由于RN和React原理相通,并且Flutter也是受React啟發(fā)迄委,很多思想也都是相通的褐筛,萬(wàn)丈高樓平地起,我們有必要深入了解一下React原理叙身。React是一個(gè)響應(yīng)式的Web框架渔扎,我們先了解一下兩個(gè)重要的概念:DOM樹(shù)與響應(yīng)式編程。
DOM樹(shù)與控件樹(shù)
文檔對(duì)象模型(Document Object Model信轿,簡(jiǎn)稱DOM)晃痴,是W3C組織推薦的處理可擴(kuò)展標(biāo)志語(yǔ)言的標(biāo)準(zhǔn)編程接口,一種獨(dú)立于平臺(tái)和語(yǔ)言的方式訪問(wèn)和修改一個(gè)文檔的內(nèi)容和結(jié)構(gòu)财忽。換句話說(shuō)倘核,這是表示和處理一個(gè)HTML或XML文檔的標(biāo)準(zhǔn)接口。簡(jiǎn)單來(lái)說(shuō)即彪,DOM就是文檔樹(shù)紧唱,與用戶界面控件樹(shù)對(duì)應(yīng),在前端開(kāi)發(fā)中通常指HTML對(duì)應(yīng)的渲染樹(shù)隶校,但廣義的DOM也可以指Android中的XML布局文件對(duì)應(yīng)的控件樹(shù)琼蚯,而術(shù)語(yǔ)DOM操作就是指直接來(lái)操作渲染樹(shù)(或控件樹(shù)), 因此惠况,可以看到其實(shí)DOM樹(shù)和控件樹(shù)是等價(jià)的概念遭庶,只不過(guò)前者常用于Web開(kāi)發(fā)中,而后者常用于原生開(kāi)發(fā)中稠屠。
響應(yīng)式編程
React中提出一個(gè)重要思想:狀態(tài)改變則UI隨之自動(dòng)改變峦睡,而React框架本身就是響應(yīng)用戶狀態(tài)改變的事件而執(zhí)行重新構(gòu)建用戶界面的工作翎苫,這就是典型的響應(yīng)式編程范式,下面我們總結(jié)一下React中響應(yīng)式原理:
開(kāi)發(fā)者只需關(guān)注狀態(tài)轉(zhuǎn)移(數(shù)據(jù))榨了,當(dāng)狀態(tài)發(fā)生變化煎谍,React框架會(huì)自動(dòng)根據(jù)新的狀態(tài)重新構(gòu)建UI。
React框架在接收到用戶狀態(tài)改變通知后龙屉,會(huì)根據(jù)當(dāng)前渲染樹(shù)呐粘,結(jié)合最新的狀態(tài)改變,通過(guò)Diff算法转捕,計(jì)算出樹(shù)中變化的部分作岖,然后只更新變化的部分(DOM操作),從而避免整棵樹(shù)重構(gòu)五芝,提高性能痘儡。
值得注意的是,在第二步中枢步,狀態(tài)變化后React框架并不會(huì)立即去計(jì)算并渲染DOM樹(shù)的變化部分沉删,相反,React會(huì)在DOM的基礎(chǔ)上建立一個(gè)抽象層醉途,即虛擬DOM樹(shù)矾瑰,對(duì)數(shù)據(jù)和狀態(tài)所做的任何改動(dòng),都會(huì)被自動(dòng)且高效的同步到虛擬DOM隘擎,最后再批量同步到真實(shí)DOM中殴穴,而不是每次改變都去操作一下DOM。為什么不能每次改變都直接去操作DOM樹(shù)嵌屎?這是因?yàn)樵跒g覽器中每一次DOM操作都有可能引起瀏覽器的重繪或回流:
如果DOM只是外觀風(fēng)格發(fā)生變化,如顏色變化恍涂,會(huì)導(dǎo)致瀏覽器重繪界面宝惰。
如果DOM樹(shù)的結(jié)構(gòu)發(fā)生變化,如尺寸再沧、布局尼夺、節(jié)點(diǎn)隱藏等導(dǎo)致,瀏覽器就需要回流(及重新排版布局)炒瘸。
而瀏覽器的重繪和回流都是比較昂貴的操作淤堵,如果每一次改變都直接對(duì)DOM進(jìn)行操作,這會(huì)帶來(lái)性能問(wèn)題顷扩,而批量操作只會(huì)觸發(fā)一次DOM更新拐邪。
思考題:Diff操作和DOM批量更新難道不應(yīng)該是瀏覽器的職責(zé)嗎?第三方框架中去做合不合適隘截?
React Native
上文已經(jīng)提到React Native 是React 在原生移動(dòng)應(yīng)用平臺(tái)的衍生產(chǎn)物扎阶,那兩者主要的區(qū)別是什么呢汹胃?其實(shí),主要的區(qū)別在于虛擬DOM映射的對(duì)象是什么东臀?React中虛擬DOM最終會(huì)映射為瀏覽器DOM樹(shù)着饥,而RN中虛擬DOM會(huì)通過(guò) JavaScriptCore 映射為原生控件樹(shù)。
JavaScriptCore 是一個(gè)JavaScript解釋器惰赋,它在React Native中主要有兩個(gè)作用:
- 為JavaScript提供運(yùn)行環(huán)境宰掉。
- 是JavaScript與原生應(yīng)用之間通信的橋梁,作用和JsBridge一樣赁濒,事實(shí)上轨奄,在iOS中,很多JsBridge的實(shí)現(xiàn)都是基于 JavaScriptCore 流部。
而RN中將虛擬DOM映射為原生控件的過(guò)程中分兩步:
1.布局消息傳遞戚绕; 將虛擬DOM布局信息傳遞給原生;
2.原生根據(jù)布局信息通過(guò)對(duì)應(yīng)的原生控件渲染控件樹(shù)枝冀;
至此舞丛,React Native 便實(shí)現(xiàn)了跨平臺(tái)。 相對(duì)于混合應(yīng)用果漾,由于React Native是原生控件渲染球切,所以性能會(huì)比混合應(yīng)用中H5好很多,同時(shí)React Native使用了Web開(kāi)發(fā)技術(shù)棧绒障,也只需維護(hù)一份代碼吨凑,同樣是跨平臺(tái)框架。
Weex
Weex是阿里巴巴于2016年發(fā)布的跨平臺(tái)移動(dòng)端開(kāi)發(fā)框架户辱,思想及原理和React Native類(lèi)似鸵钝,最大的不同是語(yǔ)法層面,Weex支持Vue語(yǔ)法和Rax語(yǔ)法庐镐,Rax 的 DSL(Domain Specific Language) 語(yǔ)法是基于 React JSX 語(yǔ)法而創(chuàng)造恩商。與 React 不同,在 Rax 中 JSX 是必選的必逆,它不支持通過(guò)其它方式創(chuàng)建組件怠堪,所以學(xué)習(xí) JSX 是使用 Rax 的必要基礎(chǔ)。而React Native只支持JSX語(yǔ)法名眉。
快應(yīng)用
快應(yīng)用是華為粟矿、小米、OPPO损拢、魅族等國(guó)內(nèi)9大主流手機(jī)廠商共同制定的輕量級(jí)應(yīng)用標(biāo)準(zhǔn)陌粹,目標(biāo)直指微信小程序。它也是采用JavaScript語(yǔ)言開(kāi)發(fā)福压,原生控件渲染申屹,與React Native和Weex相比主要有兩點(diǎn)不同:
- 快應(yīng)用自身不支持Vue或React語(yǔ)法绘证,其采用原生JavaScript開(kāi)發(fā),其開(kāi)發(fā)框架和微信小程序很像哗讥,值得一提的是小程序目前已經(jīng)可以使用Vue語(yǔ)法開(kāi)發(fā)(mpvue)嚷那,從原理上來(lái)講,Vue的語(yǔ)法也可以移植到快應(yīng)用上杆煞。
- React Native和Weex的渲染/排版引擎是集成到框架中的魏宽,每一個(gè)APP都需要打包一份,安裝包體積較大决乎;而快應(yīng)用渲染/排版引擎是集成到ROM中的队询,應(yīng)用中無(wú)需打包,安裝包體積小构诚,正因如此蚌斩,快應(yīng)用才能在保證性能的同時(shí)做到快速分發(fā)。
總結(jié)
JavaScript開(kāi)發(fā)+原生渲染的方式主要優(yōu)點(diǎn)如下:
- 采用Web開(kāi)發(fā)技術(shù)棧范嘱,社區(qū)龐大送膳、上手快、開(kāi)發(fā)成本相對(duì)較低丑蛤。
- 原生渲染叠聋,性能相比H5提高很多。
- 動(dòng)態(tài)化較好受裹,支持熱更新碌补。
不足: - 渲染時(shí)需要JavaScript和原生之間通信,在有些場(chǎng)景如拖動(dòng)可能會(huì)因?yàn)橥ㄐ蓬l繁導(dǎo)致卡頓棉饶。
JavaScript為腳本語(yǔ)言厦章,執(zhí)行時(shí)需要JIT(Just In Time),執(zhí)行效率和AOT(Ahead Of Time)代碼仍有差距照藻。 - 由于渲染依賴原生控件袜啃,不同平臺(tái)的控件需要單獨(dú)維護(hù),并且當(dāng)系統(tǒng)更新時(shí)岩梳,社區(qū)控件可能會(huì)滯后囊骤;除此之外晃择,其控件系統(tǒng)也會(huì)受到原生UI系統(tǒng)限制冀值,例如,在Android中宫屠,手勢(shì)沖突消歧規(guī)則是固定的列疗,這在使用不同人寫(xiě)的控件嵌套時(shí),手勢(shì)沖突問(wèn)題將會(huì)變得非常棘手浪蹂。
4.QT Mobile
在本篇中抵栈,我們看看最后一種跨平臺(tái)技術(shù):自繪UI+原生告材。這種技術(shù)的思路是,通過(guò)在不同平臺(tái)實(shí)現(xiàn)一個(gè)統(tǒng)一接口的渲染引擎來(lái)繪制UI古劲,而不依賴系統(tǒng)原生控件斥赋,所以可以做到不同平臺(tái)UI的一致性。注意产艾,自繪引擎解決的是UI的跨平臺(tái)問(wèn)題疤剑,如果涉及其它系統(tǒng)能力調(diào)用,依然要涉及原生開(kāi)發(fā)闷堡。這種平臺(tái)技術(shù)的優(yōu)點(diǎn)如下:
性能高隘膘;由于自繪引擎是直接調(diào)用系統(tǒng)API來(lái)繪制UI,所以性能和原生控件接近杠览。
靈活弯菊、組件庫(kù)易維護(hù)、UI外觀保真度和一致性高踱阿;由于UI渲染不依賴原生控件管钳,也就不需要根據(jù)不同平臺(tái)的控件單獨(dú)維護(hù)一套組件庫(kù),所以代碼容易維護(hù)扫茅。由于組件庫(kù)是同一套代碼蹋嵌、同一個(gè)渲染引擎,所以在不同平臺(tái)葫隙,組件顯示外觀可以做到高保真和高一致性栽烂;另外,由于不依賴原生控件恋脚,也就不會(huì)受原生布局系統(tǒng)的限制腺办,這樣布局系統(tǒng)會(huì)非常靈活。
不足:
- 動(dòng)態(tài)性不足糟描;為了保證UI繪制性能怀喉,自繪UI系統(tǒng)一般都會(huì)采用AOT模式編譯其發(fā)布包,所以應(yīng)用發(fā)布后船响,不能像Hybrid和RN那些使用JavaScript(JIT)作為開(kāi)發(fā)語(yǔ)言的框架那樣動(dòng)態(tài)下發(fā)代碼躬拢。
- 開(kāi)發(fā)效率低:QT使用C++作為其開(kāi)發(fā)語(yǔ)言,而編程效率是直接會(huì)影響APP開(kāi)發(fā)效率的见间,C++作為一門(mén)靜態(tài)語(yǔ)言聊闯,在UI開(kāi)發(fā)方面靈活性不及JavaScript這樣的動(dòng)態(tài)語(yǔ)言,另外米诉,C++需要開(kāi)發(fā)者手動(dòng)去管理內(nèi)存分配菱蔬,沒(méi)有JavaScript及Java中垃圾回收(GC)的機(jī)制。
也許你已經(jīng)猜到Flutter就屬于這一類(lèi)跨平臺(tái)技術(shù),沒(méi)錯(cuò)拴泌,F(xiàn)lutter正是實(shí)現(xiàn)一套自繪引擎魏身,并擁有一套自己的UI布局系統(tǒng)。不過(guò)蚪腐,自繪制引擎的思路并不是什么新概念箭昵,F(xiàn)lutter并不是第一個(gè)嘗試這么做的,在它之前有一個(gè)典型的代表回季,即大名鼎鼎的QT宙枷。
QT簡(jiǎn)介
Qt是一個(gè)1991年由Qt Company開(kāi)發(fā)的跨平臺(tái)C++圖形用戶界面應(yīng)用程序開(kāi)發(fā)框架。2008年茧跋,Qt Company科技被諾基亞公司收購(gòu)慰丛,Qt也因此成為諾基亞旗下的編程語(yǔ)言工具。2012年瘾杭,Qt被Digia收購(gòu)诅病。2014年4月,跨平臺(tái)集成開(kāi)發(fā)環(huán)境Qt Creator 3.1.0正式發(fā)布粥烁,實(shí)現(xiàn)了對(duì)于iOS的完全支持贤笆,新增WinRT、Beautifier等插件讨阻,廢棄了無(wú)Python接口的GDB調(diào)試支持芥永,集成了基于Clang的C/C++代碼模塊,并對(duì)Android支持做出了調(diào)整钝吮,至此實(shí)現(xiàn)了全面支持iOS埋涧、Android、WP奇瘦,它提供給應(yīng)用程序開(kāi)發(fā)者構(gòu)建圖形用戶界面所需的所有功能棘催。但是,QT雖然在PC端獲得了巨大成功耳标,備受社區(qū)追捧醇坝,然而其在移動(dòng)端卻表現(xiàn)不佳,在近幾年次坡,雖然偶爾能聽(tīng)到QT的聲音呼猪,但一直很弱,無(wú)論QT本身技術(shù)如何砸琅、設(shè)計(jì)思想如何宋距,但事實(shí)上終究是敗了,究其原因明棍,筆者認(rèn)為主要有四:
第一:QT移動(dòng)開(kāi)發(fā)社區(qū)太小乡革,學(xué)習(xí)資料不足寇僧,生態(tài)不好摊腋。
第二:官方推廣不利沸版,支持不夠。
第三:移動(dòng)端發(fā)力較晚兴蒸,市場(chǎng)已被其它動(dòng)態(tài)化框架占領(lǐng)(Hybrid和RN)视粮。
第四:在移動(dòng)開(kāi)發(fā)中,C++開(kāi)發(fā)和Web開(kāi)發(fā)棧相比有著先天的劣勢(shì)橙凳,直接結(jié)果就是QT開(kāi)發(fā)效率太低蕾殴。
基于此四點(diǎn),盡管QT是移動(dòng)端開(kāi)發(fā)跨平臺(tái)自繪引擎的先驅(qū)岛啸,但卻成為了烈士钓觉。
5.Flutter出世
“千呼萬(wàn)喚始出來(lái)”,鋪墊這么久坚踩,現(xiàn)在終于等到本書(shū)的主角出場(chǎng)了荡灾!
Flutter是Google發(fā)布的一個(gè)用于創(chuàng)建跨平臺(tái)、高性能移動(dòng)應(yīng)用的框架瞬铸。Flutter和QT mobile一樣批幌,都沒(méi)有使用原生控件,相反都實(shí)現(xiàn)了一個(gè)自繪引擎嗓节,使用自身的布局荧缘、繪制系統(tǒng)。那么拦宣,我們會(huì)擔(dān)心截粗,QT mobile面對(duì)的問(wèn)題Flutter是否也一樣,F(xiàn)lutter會(huì)不會(huì)步入QT mobile后塵鸵隧,成為另一個(gè)烈士桐愉?要回到這個(gè)問(wèn)題,我們先來(lái)看看Flutter誕生過(guò)程:
2017 年 Google I/O 大會(huì)上掰派,Google 首次推出了一款新的用于創(chuàng)建跨平臺(tái)从诲、高性能的移動(dòng)應(yīng)用框架——Flutter。
2018年2月靡羡,F(xiàn)lutter發(fā)布了第一個(gè)Beta版本系洛,同年五月, 在2018年Google I/O 大會(huì)上略步,F(xiàn)lutter 更新到了 beta 3 版本描扯。
2018年6月,F(xiàn)lutter發(fā)布了首個(gè)預(yù)覽版本趟薄,這意味著 Flutter 進(jìn)入了正式版(1.0)發(fā)布前的最后階段绽诚。
觀其發(fā)展,在2018年5月份,F(xiàn)lutter 進(jìn)入了 GitHub stars 排行榜前 100 名恩够,已有 27k star卒落。而今天(2019年5月29日),已經(jīng)有65K的Star蜂桶。經(jīng)歷了短短2年多的時(shí)間儡毕,F(xiàn)lutter 生態(tài)系統(tǒng)得以快速增長(zhǎng),由此可見(jiàn)扑媚,F(xiàn)lutter在開(kāi)發(fā)者中受到了熱烈的歡迎腰湾,其未來(lái)發(fā)展值得期待!
現(xiàn)在疆股,我們來(lái)和QT mobile做一個(gè)對(duì)比:
- 生態(tài):從Github上來(lái)看费坊,目前Flutter活躍用戶正在高速增長(zhǎng)。從Stackoverflow上提問(wèn)來(lái)看旬痹,F(xiàn)lutter社區(qū)現(xiàn)在已經(jīng)很龐大葵萎。Flutter的文檔、資源也越來(lái)越豐富唱凯,開(kāi)發(fā)過(guò)程中遇到的很多問(wèn)題都可以在Stackoverflow或其github issue中找到答案羡忘。
- 技術(shù)支持:現(xiàn)在Google正在大力推廣Flutter,F(xiàn)lutter的作者中很多人都是來(lái)自Chromium團(tuán)隊(duì)磕昼,并且github上活躍度很高卷雕。另一個(gè)角度,從今年上半年Flutter頻繁的版本發(fā)布也可以看出Google對(duì)Flutter的投入的資源不小票从,所以在官方技術(shù)支持這方面漫雕,大可不必?fù)?dān)心。
- 開(kāi)發(fā)效率:Flutter的熱重載可幫助開(kāi)發(fā)者快速地進(jìn)行測(cè)試峰鄙、構(gòu)建UI浸间、添加功能并更快地修復(fù)錯(cuò)誤。在iOS和Android模擬器或真機(jī)上可以實(shí)現(xiàn)毫秒級(jí)熱重載吟榴,并且不會(huì)丟失狀態(tài)魁蒜。這真的很棒,相信我吩翻,如果你是一名原生開(kāi)發(fā)者兜看,體驗(yàn)了Flutter開(kāi)發(fā)流后,很可能就不想重新回去做原生了狭瞎,畢竟很少有人不吐槽原生開(kāi)發(fā)的編譯速度细移。
基于以上三點(diǎn),相信讀者和筆者一樣熊锭,F(xiàn)lutter未來(lái)如何弧轧,心中自有定論雪侥。到現(xiàn)在為止,我們已經(jīng)對(duì)移動(dòng)端開(kāi)發(fā)技術(shù)有了一個(gè)全面的了解精绎,接下來(lái)我們便要進(jìn)入本書(shū)的主題速缨,你準(zhǔn)備好了嗎!
6.小結(jié)
本章主要介紹了目前移動(dòng)開(kāi)發(fā)中三種跨平臺(tái)技術(shù)捺典,現(xiàn)在我們從框架角度對(duì)比一下它們,如表1-1所示:
跨平臺(tái)技術(shù)對(duì)比
技術(shù)類(lèi)型 | UI渲染方式 | 性能 | 開(kāi)發(fā)效率 | 動(dòng)態(tài)化 | 框架代表 |
---|---|---|---|---|---|
H5+原生 | WebView渲染 | 一般 | 高 | 支持 | Cordova从祝、Ionic |
JavaScript+原生渲染 | 原生控件渲染 | 好 | 中 | 支持 | RN襟己、Weex |
自繪UI+原生 | 調(diào)用系統(tǒng)API渲染 | 好 | Flutter高, QT低 | 默認(rèn)不支持 | QT、Flutter |
上表中開(kāi)發(fā)語(yǔ)言主要指UI的開(kāi)發(fā)語(yǔ)言牍陌。而開(kāi)發(fā)效率擎浴,是指整個(gè)開(kāi)發(fā)周期的效率,包括編碼時(shí)間毒涧、調(diào)試時(shí)間贮预、以及排錯(cuò)、兼容時(shí)間契讲。動(dòng)態(tài)化主要指是否支持動(dòng)態(tài)下發(fā)代碼和是否支持熱更新仿吞。值得注意的是Flutter的Release包默認(rèn)是使用Dart AOT模式編譯的,所以不支持動(dòng)態(tài)化捡偏,但Dart還有JIT或snapshot運(yùn)行方式唤冈,這些模式都是支持動(dòng)態(tài)化的。
參考鏈接https://book.flutterchina.club/