本文已授權(quán)公眾號(hào)【縵圖技術(shù)團(tuán)隊(duì)】發(fā)布
詳解flutter刷新流程,讓你的應(yīng)用更流暢
一、概述
Flutter?
是谷歌推出的高性能、跨端UI
框架,可以通過一套代碼,支持?iOS
、Android
、Windows/MAC/Linux?
等多個(gè)平臺(tái),且能達(dá)到原生性能。Flutter?
也可以與平臺(tái)原生代碼進(jìn)行混合開發(fā),其更新迭代速度很快,技術(shù)發(fā)展也日趨成熟,如今已經(jīng)有很多公司在使用這種新跨端技術(shù)。我們知道在?flutter?
中可以使用?setState()?
來刷新?StatefulWidget?
的?UI
,這會(huì)遍歷調(diào)用子?Widget?
的?build()?
重構(gòu)視圖。當(dāng)一個(gè)頁面內(nèi)容比較復(fù)雜時(shí),會(huì)包含多個(gè)?widget
,如果直接調(diào)用根組件的?setState()
,會(huì)遍歷所有子?Widget?
的?build()
,刷新整個(gè)頁面,這樣會(huì)造成很多不必要的開銷,刷新的成本相對較大。如果數(shù)據(jù)很多接口響應(yīng)又慢的話,還會(huì)有界面閃爍的現(xiàn)象。那么?flutter?
到底是如何實(shí)現(xiàn)界面刷新的,調(diào)用?setState({})
后?flutter?
的framework?
到底做了哪些操作?接下來我們一起來揭開?flutter?
刷新界面的神秘面紗。
二、Flutter 渲染中的三棵樹
在了解flutter
的刷新機(jī)制之前,先來看看flutter
渲染過程中的三棵樹。在Flutter
的渲染過程中由Widget
,Element
,RenderObject
這個(gè)三個(gè)元素組成三棵樹。Widget
控件樹,Element?
元素樹,RenderObject?
渲染樹。Widget
內(nèi)部調(diào)用?createElement()
會(huì)創(chuàng)建對應(yīng)的?Element
,Element
內(nèi)部調(diào)用?createRenderObject()
會(huì)創(chuàng)建對應(yīng)的?RenderObject
,所以我們只需要關(guān)心?Widget?
就可以快速的構(gòu)建視圖界面了。為什么使用三棵樹而不是?Widget?
和RenderObject?
兩棵樹呢?這里是為了復(fù)用?Element?
提升渲染性能,因?yàn)?Widget?
面向業(yè)務(wù)它的改變會(huì)很頻繁,如果根據(jù)?Widget?
直接生成?RenderObject?
會(huì)導(dǎo)致渲染性能下降。

RenderObject?
渲染樹在上屏前會(huì)生成一棵?Layer?
樹去進(jìn)行屏幕渲染。
三、刷新流程分析
在開始流程分析之前,先上個(gè)圖來梳理下整個(gè)刷新流程,腦海里對整體先有個(gè)初步認(rèn)識(shí),這樣再跟著下面的源碼一步步往里深入分析,思路會(huì)更加清晰一些:

對整體的刷新流程有了大概的認(rèn)識(shí)之后,我們對照著上面這個(gè)圖的流程來看看調(diào)用setState({})
之后,系統(tǒng)具體都做了哪些操作:
注:
setState() 源碼位于 flutetr_sdk/packages/flutter/lib/src/widgets/framework.dart 文件中
本文源碼基于 Flutter 3.3.8 Dart 2.18.4 ? DevTools 2.15.0文章來源:http://www.zghlxwxcb.cn/news/detail-551233.html
@protected
void setState(VoidCallback fn) {
assert(fn != null);
assert(() {
if (_debugLifecycleState == _StateLifecycle.defunct) {
throw FlutterError.fromParts(<DiagnosticsNode>[
// 省略不重要代碼
]);
}
if (_debugLifecycleState == _StateLifecycle.created && !mounted) {
throw FlutterError.fromParts(<DiagnosticsNode>[
// 省略不重要代碼
]);
}
return true;
}());
final Object? result = fn() as dynamic;
...
// 省略不重要代碼
_element!.markNeedsBuild();
}
setState()?
中傳入的回調(diào)函數(shù)是立刻同步執(zhí)行的,不能是異步的。該方法前面主要是 assert
部分的一些校驗(yàn)邏輯,不允許傳入的回調(diào)函數(shù)為null
且不能為異步函數(shù),這里有一個(gè)點(diǎn)需要注意:在?widget?
構(gòu)造函數(shù)中以及?dispose?
調(diào)用之后,不允許再調(diào)用?setState()?
方法去刷新界面,可以在調(diào)用前考慮使用?mounted?
標(biāo)志來檢測該?widget?
是否還掛載在?文章來源地址http://www.zghlxwxcb.cn/news/detail-551233.html
到了這里,關(guān)于詳解flutter刷新流程,讓你的應(yīng)用更流暢的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!