一、什么是flutter
Flutter是谷歌的移動(dòng)UI框架,可以快速在iOS和Android上構(gòu)建高質(zhì)量的原生用戶界面蓬推。 Flutter可以與現(xiàn)有的代碼一起工作。在全世界澡腾,F(xiàn)lutter正在被越來(lái)越多的開(kāi)發(fā)者和組織使用沸伏,并且Flutter是完全免費(fèi)、開(kāi)源的动分。
跨平臺(tái)的幾種方案:
1毅糟、cordova為例的web應(yīng)用(微信小程序)
2、原生繪制澜公,如rn姆另、weex
JavaScript通過(guò) bridge 傳遞到native完成原生繪制, UI的渲染是很頻繁的坟乾,要使UI不卡頓迹辐,必須達(dá)到60Fps。但是橋接會(huì)花一定的時(shí)間甚侣。所以這樣的架構(gòu)有時(shí)候會(huì)有性能問(wèn)題明吩。
3、Flutter
使用底層引擎渲染視圖:Skia殷费,省去了轉(zhuǎn)換為原生控件的流程
跨端對(duì)比:(RN和Flutter印荔,數(shù)據(jù)來(lái)自閑魚)
1、Flutter在低端和中端的iOS機(jī)型上详羡,F(xiàn)PS的表現(xiàn)都優(yōu)于RN
2仍律、CPU方面,F(xiàn)lutter在低端機(jī)上表現(xiàn)差于RN实柠,中端優(yōu)于RN
3水泉、內(nèi)存方面,低端機(jī)Flutter和RN表現(xiàn)幾乎一致窒盐,但是中端機(jī)型上會(huì)多余30MB的內(nèi)存(分析為Dart VM的內(nèi)存)
Flutter框架:
跨平臺(tái)應(yīng)用的框架草则,沒(méi)有使用WebView或者系統(tǒng)平臺(tái)自帶的控件,使用自身的高性能渲染引擎(Skia)自繪登钥,
界面開(kāi)發(fā)語(yǔ)言使用dart,底層渲染引擎使用C, C++
組合大于繼承娶靡,控件本身通常由許多小型牧牢、單用途的控件組成,結(jié)合起來(lái)產(chǎn)生強(qiáng)大的效果,類的層次結(jié)構(gòu)是扁平的塔鳍,以最大化可能的組合數(shù)量
二伯铣、Widget介紹
StatefullWidget vs StatelessWidget
一棵完整的Widget樹(shù):
在 Flutter 體系結(jié)構(gòu)中,真正做組件渲染在屏幕上這個(gè)任務(wù)的并非在 控件層(Widget)層轮纫,而是在渲染(Rendering)層腔寡。Flutter 中又引入了 Element 樹(shù)和 RenderingObject 樹(shù)兩棵樹(shù)。
創(chuàng)建樹(shù):
Widget&Element&RenderObject
Widget 是應(yīng)用界面的聲明信息掌唾。Widget樹(shù)實(shí)際上是一個(gè)配置樹(shù)放前,Widget一般來(lái)說(shuō)是不可變的immutable
Element 鏈接 Widget 和 RenderObject,管理界面的更新和修改糯彬。
RenderObject 保存具體的布局信息凭语,負(fù)責(zé)繪制 UI。
更新樹(shù):
為什么widget都是immutable撩扒?
flutter界面開(kāi)發(fā)是一種響應(yīng)式編程似扔,主張simple is fast,flutter設(shè)計(jì)的初衷希望數(shù)據(jù)變更時(shí)發(fā)送通知到對(duì)應(yīng)的可變更節(jié)點(diǎn)(可能是一個(gè)StatefullWidget子節(jié)點(diǎn),也可以是rootWidget),由上到下重新create widget樹(shù)進(jìn)行刷新搓谆,這種思路比較簡(jiǎn)單炒辉,不用關(guān)心數(shù)據(jù)變更會(huì)影響到哪些節(jié)點(diǎn)。
widget重新創(chuàng)建泉手,element樹(shù)和renderObject樹(shù)是否也重新創(chuàng)建黔寇?
widget只是一個(gè)配置數(shù)據(jù)結(jié)構(gòu),創(chuàng)建是非常輕量的螃诅,加上flutter團(tuán)隊(duì)對(duì)widget的創(chuàng)建/銷毀做了優(yōu)化啡氢,不用擔(dān)心整個(gè)widget樹(shù)重新創(chuàng)建所帶來(lái)的性能問(wèn)題,但是renderobject就不一樣了术裸,renderobject涉及到layout倘是、paint等復(fù)雜操作,是一個(gè)真正渲染的view袭艺,整個(gè)view 樹(shù)重新創(chuàng)建開(kāi)銷就比較大搀崭,所以答案是否定的。
樹(shù)的更新規(guī)則:
找到widget對(duì)應(yīng)的element節(jié)點(diǎn)猾编,設(shè)置element為dirty瘤睹,觸發(fā)drawframe, drawframe會(huì)調(diào)用element的performRebuild()進(jìn)行樹(shù)重建
widget.build() == null, deactive element.child,刪除子樹(shù),流程結(jié)束
element.child.widget == NULL, mount 的新子樹(shù)答倡,流程結(jié)束
element.child.widget == widget.build() 無(wú)需重建轰传,否則進(jìn)入流程5
Widget.canUpdate(element.child.widget, newWidget) == true,更新child的slot瘪撇,element.child.update(newWidget)(如果child還有子節(jié)點(diǎn)获茬,則遞歸上面的流程進(jìn)行子樹(shù)更新),流程結(jié)束港庄,否則轉(zhuǎn)6
Widget.canUpdate(element.child.widget, newWidget) != true(widget的classtype 或者 key 不相等)恕曲,deactivew element.child鹏氧,mount 新子樹(shù)
如何觸發(fā)樹(shù)更新:
全局更新:調(diào)用runApp(rootWidget),一般flutter啟動(dòng)時(shí)調(diào)用后不再會(huì)調(diào)用
局部子樹(shù)更新, 將該子樹(shù)做StatefullWidget的一個(gè)子widget佩谣,并創(chuàng)建對(duì)應(yīng)的State類實(shí)例把还,通過(guò)調(diào)用state.setState() 觸發(fā)該子樹(shù)的刷新
三、數(shù)據(jù)傳輸
Flutter定義了三種不同類型的Channel茸俭,它們分別是
BasicMessageChannel:用于傳遞字符串和半結(jié)構(gòu)化的信息吊履。
MethodChannel:用于傳遞方法調(diào)用(method invocation)。
EventChannel: 用于數(shù)據(jù)流(event streams)的通信瓣履。
三種Channel之間互相獨(dú)立率翅,各有用途,但它們?cè)谠O(shè)計(jì)上卻非常相近袖迎。每種Channel均有三個(gè)重要成員變量:
name: String類型冕臭,代表Channel的名字,也是其唯一標(biāo)識(shí)符燕锥。
messager:BinaryMessenger類型辜贵,代表消息信使,是消息的發(fā)送與接收的工具归形。
codec: MessageCodec類型或MethodCodec類型托慨,代表消息的編解碼器。
PlatformChannel:http://www.reibang.com/p/39575a90e820
外接紋理:https://juejin.cn/post/6844903662548942855