移動(dòng)開(kāi)發(fā)漫談
移動(dòng)開(kāi)發(fā)在IT開(kāi)發(fā)行業(yè)算是一個(gè)比較年輕的門(mén)類(lèi),2008年蘋(píng)果公司才發(fā)布了iOS SDK胁勺,2009年谷歌發(fā)布了Android SDK,分別基于Objective-C和Java兩門(mén)比較古老的語(yǔ)言開(kāi)發(fā)独旷,后來(lái)雙方陸續(xù)推出了swift和kotlin兩門(mén)現(xiàn)代語(yǔ)言來(lái)普及自己的優(yōu)勢(shì)署穗。在原生開(kāi)發(fā)的領(lǐng)域之外寥裂,也有各種各樣的跨平臺(tái)開(kāi)發(fā)技術(shù)層出不窮。下面我們簡(jiǎn)單聊一下各自的特點(diǎn)蛇捌。
webview
第一種解決方案是基于JavaScript and WebViews來(lái)實(shí)現(xiàn)的抚恒,其中的代表為PhoneGap, Apache Cordova,他們將項(xiàng)目?jī)?nèi)需要?jiǎng)討B(tài)展示的頁(yè)面(新聞络拌、商品之類(lèi))通過(guò)原生的webview控件來(lái)加載出來(lái),這樣一來(lái)回溺,這個(gè)模塊不需要經(jīng)過(guò)發(fā)版春贸,審核一個(gè)比較漫長(zhǎng)的過(guò)程也可以實(shí)現(xiàn)一次代碼,兩個(gè)平臺(tái)運(yùn)行遗遵。
在iOS?SDK和Android SDK的幫助下萍恕,我們可以訪問(wèn)該平臺(tái)下的所有功能。但是webview不同车要,本質(zhì)上仍然是運(yùn)行在一個(gè)受限的沙盒環(huán)境允粤,對(duì)于藍(lán)牙,通訊等必須由該平臺(tái)才能完成的功能翼岁,通常我們需要借助bridge來(lái)實(shí)現(xiàn)类垫,webview 通過(guò) jsbridge 這個(gè)橋梁來(lái)實(shí)現(xiàn)js和原生之間的通訊,開(kāi)放相應(yīng)的接口琅坡,實(shí)現(xiàn)上下文的切換悉患。參照下圖
但是由于多了一層通訊和本身的問(wèn)題,webview的解決方案在性能方面并沒(méi)有太出色榆俺。對(duì)于復(fù)雜的界面和動(dòng)畫(huà)售躁,都不是很理想。
RN 和 Weex
webview的解決方案將業(yè)務(wù)和繪制都交給了自己來(lái)解決再加上有限的環(huán)境茴晋,所以很多場(chǎng)景不堪重任陪捷,于是出現(xiàn)了js開(kāi)發(fā)+原生渲染的解決方案。
React Native 是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利用js構(gòu)建在iOS和安卓上運(yùn)行的應(yīng)用掀虎,它使用與React相同的設(shè)計(jì)凌盯,以數(shù)據(jù)變化驅(qū)動(dòng)ui變化,通過(guò)js core 將虛擬DOM映射為安卓和iOS上原生的控件烹玉,相對(duì)于webview來(lái)說(shuō)驰怎,RN是原生控件渲染,所以在性能上的表現(xiàn)要好很多(rn是react在原生平臺(tái)的衍生產(chǎn)物二打,同樣的flutter也借鑒了react很多東西县忌,在很多思想上有很多相似的地方)。
weex是國(guó)內(nèi)阿里巴巴退出的跨平臺(tái)開(kāi)發(fā)解決方案,也是用js開(kāi)發(fā)+原生渲染症杏,但是生態(tài)環(huán)境和rn比還有些差距装获,和rn最大的地方在于語(yǔ)法層面上的不同。
這部分的通訊流參照下圖
總的來(lái)說(shuō)厉颤,這種方式已經(jīng)很成熟了穴豫,采用web開(kāi)發(fā)技術(shù)棧,前端人員好上手逼友。原生渲染精肃,性能上明顯提升。有熱更新動(dòng)態(tài)化技術(shù)解決方案帜乞。但是渲染上需要和原生通信不斷拖動(dòng)的場(chǎng)景下仍然有時(shí)候會(huì)出現(xiàn)卡頓等不好的體驗(yàn)司抱,
Flutter
Flutter采用了自繪UI+原生的方式來(lái)解決了跨平臺(tái)開(kāi)發(fā)方案,它沒(méi)有用腳本語(yǔ)言而是采用了不同的方案黎烈,通過(guò)編譯語(yǔ)言Dart加上自繪引擎來(lái)避免了繪制UI時(shí)候的頻繁通信(解決了UI的通信习柠,如果需要平臺(tái)下的其他能力仍然需要通信)Dart編譯成本平臺(tái)代碼,無(wú)需頻繁切換上下文照棋,避免了性能消耗资溃,縮短了啟動(dòng)時(shí)間。我們下面著重說(shuō)明一下Flutter必怜。
Flutter簡(jiǎn)介
flutter是什么肉拓?Flutter是Google發(fā)布的一個(gè)用于創(chuàng)建跨平臺(tái)、高性能的移動(dòng)應(yīng)用程序SDK梳庆。他包括了一個(gè)現(xiàn)代的響應(yīng)式框架暖途、一個(gè)2D渲染引擎、現(xiàn)成的widget和開(kāi)發(fā)工具膏执,通過(guò)這些我們可以快速的實(shí)現(xiàn)構(gòu)建驻售,調(diào)試,還原一個(gè)精致的應(yīng)用更米。我們可以書(shū)寫(xiě)一份精簡(jiǎn)的代碼欺栗,同時(shí)開(kāi)發(fā)iOS和Android,通過(guò)大量的多是多樣的widget組合構(gòu)建Material Design和Cupertino風(fēng)格的APP征峦。
跨平臺(tái)自繪
我們上面提到過(guò)迟几,flutterUI繪制方面沒(méi)有采用原生的控件,而是通過(guò)了自家的跨平臺(tái)2D渲染引擎skia來(lái)繪制UI栏笆,直接調(diào)用的系統(tǒng)界別的api类腮,避免了大量的上下文切換通信帶來(lái)的性能損耗問(wèn)題,也可以避免對(duì)原生控件的依賴(lài)蛉加。
開(kāi)發(fā)語(yǔ)言Dart
Dart也是谷歌自家的語(yǔ)言蚜枢,F(xiàn)lutter采用了Dart來(lái)開(kāi)發(fā)而不是用js缸逃。Dart是一門(mén)現(xiàn)代語(yǔ)言,你可以看到很多現(xiàn)代語(yǔ)言擁有的優(yōu)點(diǎn)厂抽,簡(jiǎn)單易學(xué)需频,易于上手。更重要的是Dart支持開(kāi)發(fā)階段的的JIT和發(fā)包時(shí)候的AOT筷凤,在開(kāi)發(fā)周期時(shí)候的熱重載特點(diǎn)可以大量提高你在開(kāi)發(fā)時(shí)候的效率昭殉,而發(fā)包時(shí)候,可以通過(guò)AOT生成高效的ARM代碼以保證應(yīng)用性能嵌施,想對(duì)應(yīng)的js就不能實(shí)現(xiàn)饲化。
Dart語(yǔ)法就參考官網(wǎng)了,例如可選類(lèi)型吗伤、閉包、庫(kù)硫眨、詞法作用域足淆、頂層函數(shù)、命名參數(shù)礁阁、async/await等等巧号。一些優(yōu)秀的設(shè)計(jì)都有,話說(shuō)你從swift1學(xué)到了swift4還有什么不易學(xué)呢哈哈姥闭,開(kāi)個(gè)玩笑丹鸿。
widget
這個(gè)概念在flutter里很重要很重要!可以說(shuō)理解了widget對(duì)于你書(shū)寫(xiě)flutter有著至關(guān)重要的作用棚品。在flutter的世界里靠欢,萬(wàn)物皆widget。
與其他將視圖铜跑、控制器门怪、布局和其他屬性分離的框架不同,F(xiàn)lutter具有一致的統(tǒng)一對(duì)象模型:widget锅纺。widget本身就分很多種掷空,有布局類(lèi)的,基礎(chǔ)控件類(lèi)的囤锉,功能性的坦弟,手勢(shì),幫助類(lèi)的等等等等官地,可以說(shuō)凡是你看到的都是widget酿傍。
Widget根據(jù)布局形成一個(gè)層次結(jié)構(gòu)。每個(gè)widget嵌入其中区丑,并繼承其父項(xiàng)的屬性拧粪。沒(méi)有單獨(dú)的“應(yīng)用程序”對(duì)象修陡,相反,根widget扮演著這個(gè)角色可霎。你可以想著整個(gè)應(yīng)用魄鸦,每一個(gè)頁(yè)面都是一個(gè)widget套著一個(gè)widget。在flutter中癣朗,自定義widget的時(shí)候相比原生開(kāi)發(fā)來(lái)講并不多拾因,更多時(shí)候我們是將不同的widget組合起來(lái)來(lái)拼成我們想要的模樣。
Flutter結(jié)構(gòu)
我們可以看到分為Framework 和Engine兩層旷余。
Engine層面是有c++寫(xiě)的绢记,其中包括了 Skia引擎、Dart運(yùn)行時(shí)正卧、文字排版引擎等蠢熄。在代碼調(diào)用?dart:ui庫(kù)時(shí),調(diào)用最終會(huì)走到Engine層炉旷,然后實(shí)現(xiàn)真正的繪制邏輯签孔。
通常我們用的更多的是Framework層面的東西,這是由Dart實(shí)現(xiàn)的窘行。從高到底饥追,依次深入,我們可以用更少的代碼來(lái)實(shí)現(xiàn)更多的事情罐盔,也可以深入到下面自繪view但绕。
這篇文章就聊到這里,接下來(lái)簡(jiǎn)單對(duì)比下flutter和iOS里面一些概念的對(duì)比惶看。