本篇文章是學(xué)習(xí)fluter的部分內(nèi)容總結(jié)
跨平臺根據(jù)其原理环葵,主要分為三類:
1.H5+原生(Cordova参淹,Ionic幕袱,微信小程序)
h5代碼是運(yùn)行在webview中祝谚,而webview實(shí)質(zhì)上就是一個瀏覽器內(nèi)核,其JavaScript依然運(yùn)行在一個權(quán)限受限的沙箱中昵骤,所以對于大多數(shù)系統(tǒng)能力都沒有訪問權(quán)限树碱,如無法訪問文件系統(tǒng),不能使用藍(lán)牙等变秦。
2.JavaScript開發(fā)+原生渲染(React Native,Weex,快應(yīng)用)
主要優(yōu)點(diǎn)如下:
1.采用web開發(fā)技術(shù)棧成榜,社區(qū)龐大,上手快蹦玫,開發(fā)成本相對較低赎婚。
2.原生渲染,性能相對h5提高很多
3.動態(tài)化較好樱溉,支持熱更新
不足:
1.渲染時需要Javascript和原聲之間通訊挣输,在有些場景如拖動可能會因?yàn)橥ㄓ嶎l繁導(dǎo)致卡頓。
2.JavaScript為腳本語言福贞,執(zhí)行時需要JIT(動態(tài)編譯)撩嚼,執(zhí)行效率和AOT(靜態(tài)編譯)代碼仍有差距
3.由于渲染依賴原聲控件,不同平臺的空間需要單獨(dú)維護(hù),并且當(dāng)系統(tǒng)更新時完丽,社區(qū)控件可能會滯后向瓷,除此之外,其控件系統(tǒng)也會受到原聲UI系統(tǒng)限制舰涌。例如猖任,在Android中,手勢沖突消歧規(guī)則是固定的瓷耙,這在使用不同人寫的控件嵌套時朱躺,手勢沖突問題會變得非常棘手。
3.自繪UI+原生(QT for mobile搁痛,F(xiàn)lutter)
通過在不同平臺實(shí)現(xiàn)一個統(tǒng)一接口的渲染引擎來繪制UI长搀,而不依賴系統(tǒng)原聲控件,所以可以做到不同平臺UI的一致性鸡典。
優(yōu)點(diǎn):
1.性能高
2.靈活源请,組件庫易維護(hù),UI外觀保真度和一致性高
不足:
動態(tài)性不足彻况,為了保證UI繪制性能谁尸,自繪UI系統(tǒng)一般都會采用AOT模式編譯其發(fā)布包,所以應(yīng)用發(fā)布后纽甘,不能像Hybird和RN那些使用JS作為開發(fā)語言的框架那樣動態(tài)下發(fā)代碼良蛮。
程序主要有兩種運(yùn)行方式:
靜態(tài)編譯和動態(tài)解釋。靜態(tài)編譯的程序在執(zhí)行前全部被翻譯為機(jī)器碼悍赢,通常將這種類型成為AOT决瞳,即“提前編譯”;而解釋執(zhí)行的則是一句一句邊翻譯邊運(yùn)行左权,通常將這種類型成為JIT皮胡,即“即時編譯”。
Flutter款架結(jié)構(gòu):
Dart語言
變量聲明
1.var
類似于JavaScript中的var,他可以接收任何類型的變量赏迟,但最大的不同時Dart中var變量一旦賦值屡贺,類型便會確定,則不能再改變其類型瀑梗。
2.dynamic和object
Dynamic和Object與var功能相似烹笔,都會在賦值時自動進(jìn)行類型推斷裳扯,不同在于抛丽,賦值后可以改變其類型。
object時dart所有對象的根基類饰豺,也就是說所有類型都是Object的子類亿鲜,所以任何類型的數(shù)據(jù)都可以賦值給Object聲明的對象,所以表現(xiàn)效果和dynamic相似
3.final和const
如果您從未打算更改一個變量,name使用final或const蒿柳,不是var饶套,也不是一個類型。一個final變量只能被設(shè)置一次垒探,兩者區(qū)別在于:const變量是一個編譯時常量妓蛮,final變量在第一次使用時被初始化。被final或者const修飾的變量圾叼,變量類型可以省略蛤克。
函數(shù)
dart是一種真正的面向?qū)ο蟮恼Z言,所以即使是函數(shù)也是對象夷蚊,并且有一個類型Function构挤。這意味著函數(shù)可以賦值給變量或者作為參數(shù)傳遞給其他函數(shù),這是函數(shù)式編程的典型特征惕鼓。
異步支持
dart類庫有非常多的返回future或者stream對象的函數(shù)筋现。這些函數(shù)被稱為異步函數(shù):他們只會在設(shè)置好一些耗時操作之后返回,比如像IO操作箱歧。而不是等到這個操作完成矾飞。
async和await關(guān)鍵詞支持了異步編程,運(yùn)行您寫出和同步代碼很像的異步代碼呀邢。
future與JavaScript的promise非常相似凰慈,表示一個異步操作的最終完成(或失敗)及其結(jié)果值的表示驼鹅。簡單來說微谓,他就是用來處理異步操作的,異步處理成功就執(zhí)行成功的操作输钩,異步處理失敗就捕獲錯誤或者停止后續(xù)操作豺型。一個future只會對應(yīng)一個結(jié)果,要么成功买乃,要么失敗姻氨。
stream也是用于接收異步事件數(shù)據(jù),和future不同的是剪验,他可以接收多個異步操作的結(jié)果(成功或失旊群浮)。也就是說功戚,在執(zhí)行異步任務(wù)時娶眷,可以通過多次觸發(fā)成功或失敗事件來傳遞結(jié)果數(shù)據(jù)或錯誤異常。stream常用于多次讀取數(shù)據(jù)的異步任務(wù)場景啸臀,如網(wǎng)絡(luò)內(nèi)容下載届宠,文件讀寫等。
Dart線程模型及異常捕獲
在Dart中,所有的外部事件任務(wù)都在事件隊列中豌注,如IO伤塌、計時器、點(diǎn)擊轧铁、以及繪制事件等每聪,而微任務(wù)通常來源于Dart內(nèi)部,并且微任務(wù)非常少齿风,之所以如此熊痴,是因?yàn)槲⑷蝿?wù)隊列優(yōu)先級高,如果微任務(wù)太多聂宾,執(zhí)行時間總和就越久果善,事件隊列任務(wù)的延遲也就越久,對于GUI應(yīng)用來說最直觀的表現(xiàn)就是比較卡系谐,所以必須得保證微任務(wù)隊列不會太長巾陕。
在事件循環(huán)中,當(dāng)某個任務(wù)發(fā)生異常并沒有被捕獲時纪他,程序并不會退出鄙煤,而直接導(dǎo)致的結(jié)果是當(dāng)前任務(wù)的后續(xù)代碼就不會被執(zhí)行了,也就是說一個任務(wù)中的異常是不會影響其它任務(wù)執(zhí)行的茶袒。
最終異常捕獲:
void collectLog(String line){
... //收集日志
}
void reportErrorAndLog(FlutterErrorDetails details){
... //上報錯誤和日志邏輯
}
FlutterErrorDetails makeDetails(Object obj, StackTrace stack){
...// 構(gòu)建錯誤信息
}
void main() {
FlutterError.onError = (FlutterErrorDetails details) {
reportErrorAndLog(details);
};
runZoned(
() => runApp(MyApp()),
zoneSpecification: ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
collectLog(line); //手機(jī)日志
},
),
onError: (Object obj, StackTrace stack) {
var details = makeDetails(obj, stack);
reportErrorAndLog(details);
},
);
}