Dart語(yǔ)言都是值傳遞,每次調(diào)用函數(shù)都是傳遞對(duì)象的內(nèi)存地址,而不是復(fù)制對(duì)象
優(yōu)點(diǎn):熱重載(Hot Reload)
缺點(diǎn):不支持熱更新,三方庫(kù)有限,需要自己造輪子
Flutter的FrameWork層是用Drat編寫(xiě)的框架(SDK),它實(shí)現(xiàn)了一套基礎(chǔ)庫(kù),組件庫(kù),比Engine上層
Flutter的Engine層是Skia 2D的繪圖引擎庫(kù),跟GPU交互
StatelessWidget: 一旦創(chuàng)建就不關(guān)心任何變化,在下次構(gòu)建之前都不會(huì)改變;
StatefulWidget: 在生命周期內(nèi),該類(lèi)Widget所持有的數(shù)據(jù)可能會(huì)發(fā)生變化,這樣的數(shù)據(jù)被稱(chēng)為State;
1.生命周期:
StatefulWidget ---->? initState? ----->? didChangeDependencies? ----> build (中間會(huì)插入 didUpdateWidget)? ----> deactivate? ---->? dispose
2. 這個(gè)就是Flutter面向?qū)ο?/h4>
繼承 extends? ?混入mixins? 接口實(shí)現(xiàn) implements
優(yōu)先繼承,其次混入,最后接口實(shí)現(xiàn)
mixins不能有構(gòu)造函數(shù),其實(shí)也是單繼承;
抽象類(lèi)abstract:父類(lèi)可以只聲明,不實(shí)現(xiàn);由子類(lèi)去實(shí)現(xiàn);
私有變量加_,其他默認(rèn)公開(kāi)
3.Flutter渲染三棵樹(shù)
WidgetTree:存放渲染內(nèi)容,只是一個(gè)配置數(shù)據(jù)結(jié)構(gòu);
Element:中間層,同時(shí)持有Widget和RenderObject,會(huì)去遍歷視圖樹(shù);
RenderObject:負(fù)責(zé)真正的界面布局和渲染,包含大小和布局等信息,實(shí)例化RenderObject很耗時(shí);
4.Widget分類(lèi)
組合類(lèi):StatefulWidget和StatelessWidget
代理類(lèi):inheritedWidget和parentDataWidget:通過(guò)context獲取共享狀態(tài)
繪制類(lèi):RenderObjectWidget:布局相關(guān)方法調(diào)用順序:layout(準(zhǔn)備布局) --->performResize(計(jì)算大小)? ---> performLayout(開(kāi)始布局) ---> markNeedPaints(是否需要重繪)
5.單訂閱和多訂閱(Stream)
single和broadcast;Stream 默認(rèn)處于單訂閱模式,所以同一個(gè) stream 上的 listen 和其它大多數(shù)方法只能調(diào)用一次,調(diào)用第二次就會(huì)報(bào)錯(cuò)。但 Stream 可以通過(guò) transform() 方法(返回另一個(gè) Stream)進(jìn)行連續(xù)調(diào)用。通過(guò) Stream.asBroadcastStream() 可以將一個(gè)單訂閱模式的 Stream 轉(zhuǎn)換成一個(gè)多訂閱模式的 Stream
6.Widget? ?State? ?Context
Widget:Widget就是可視化組件,里面的結(jié)構(gòu)是樹(shù)狀的,所以說(shuō)是WidgetTree,父Widget和子Widget;
State:是StatefulWidget的實(shí)例化行為,可以交互和干預(yù)Widget的狀態(tài)和布局,任何變更都會(huì)觸發(fā)重建Widget;
Context:每一個(gè)Widget都會(huì)有對(duì)應(yīng)的Widget,用來(lái)描述它的位置引用,是Widget樹(shù)的一部分;
7.Isolate執(zhí)行順序和Future,Stream的區(qū)別
Main(主事件)? --->? ? MicroTask(微事件)? ?---->? EventQueue(事件循環(huán));
最后就在微事件和事件循環(huán)中反復(fù)循環(huán),并且遵循先進(jìn)先出
Isolate實(shí)際是一個(gè)隔離的Dart上下文環(huán)境(容器)。并且不同的Isolate線(xiàn)程之間的通信通過(guò)port來(lái)異步進(jìn)行,在內(nèi)存上是隔離開(kāi)的
耗時(shí)長(zhǎng)的并且影響應(yīng)用流暢性的就用Isolate(比如圖片處理,JSON解析),如果耗時(shí)短的就用Future;
Isolate.spawn() 和Isolate.exit()
Future表示延遲運(yùn)行的對(duì)象,用來(lái)表示一個(gè)潛在的值返回或錯(cuò)誤返回,這個(gè)返回值將在未來(lái)的某個(gè)時(shí)刻才可用。Future的調(diào)用者可以注冊(cè)回調(diào),一旦返回值或錯(cuò)誤可用,就可以通過(guò)回調(diào)函數(shù)對(duì)其進(jìn)行處理。
Future.delayed:創(chuàng)建在延遲一定時(shí)間后運(yùn)行的Future
Future.microtask:創(chuàng)建包含使用scheduleMicrotask異步調(diào)用計(jì)算的結(jié)果的Future
Future.value:創(chuàng)建一個(gè)有值返回的Future
Future.sync:返回包含立即調(diào)用計(jì)算結(jié)果的future
Stream:在Dart中,Stream 和 Future 一樣,都是用來(lái)處理異步編程的工具。它們的區(qū)別在于,Stream 可以接收多個(gè)異步結(jié)果,而Future 只有一個(gè)。多個(gè)是asBroadcastStream()。
await for 如何使用?
await for是不斷獲取stream流中的數(shù)據(jù),然后執(zhí)行循環(huán)體中的操作。它一般用在直到stream什么時(shí)候完成,并且必須等待傳遞完成之后才能使用,不然就會(huì)一直阻塞
8.組件渲染怎么完成的
通過(guò)代碼來(lái)構(gòu)建視圖結(jié)構(gòu)數(shù)據(jù),然后通過(guò)Skia圖像引擎加工成GPU數(shù)據(jù),最后通過(guò)OpenGL提供給GPU渲染
9.PlatformView原理
Platform view 就是 AndroidView 和 UIKitView 的總稱(chēng),允許將native view嵌入到Widget體系中,完成Dart對(duì)native view的控制;
Platform view 是在 native 側(cè)渲染的,并且底層實(shí)際是使用texture實(shí)現(xiàn),通過(guò)_textureId來(lái)展示,所以Platform view開(kāi)銷(xiāo)很大。因?yàn)樾枰獜腉PU切換到CPU,然后再切換到GPU,所以盡量避免使用Platform view;一般使用是webView;
Platform view大小由父節(jié)點(diǎn)的大小來(lái)控制,所以需要用Expanded包裹,不然就是父視圖的大小;
10.Flutter 線(xiàn)程管理模型
線(xiàn)程管理模型:Flutter Engine會(huì)創(chuàng)建一個(gè)isolate,dart代碼運(yùn)行在這個(gè)主isolate上,新創(chuàng)建的isolate由flutter進(jìn)行統(tǒng)一管理。
Flutter的線(xiàn)程管理由一個(gè)叫Embeder的中間層組件控制,Embeder提供了四個(gè)Task,分別是UITaskRunner、IOTaskRunner、GPUTaskRunner、platformTaskRunner
UITaskRunner:負(fù)責(zé)綁定渲染相關(guān)的操作,如timer,microtask,異步io操作;
IOTaskRunner:處理圖片數(shù)據(jù),為gpu渲染做準(zhǔn)備,比如讀取磁盤(pán)壓縮圖片的格式,將解壓成gpu能處理的格式,并傳給gpu,因其比較消耗性能所以單獨(dú)開(kāi)一個(gè)線(xiàn)程。
GPUTaskRunner:用于執(zhí)行g(shù)pu指令,負(fù)責(zé)將layer tree提供的信息轉(zhuǎn)換為平臺(tái)可執(zhí)行的gpu指令
platformTaskRunner:所有接口調(diào)用都使用該接口,長(zhǎng)時(shí)間卡頓將會(huì)被watchdog強(qiáng)殺。
11.Flutter狀態(tài)管理
狀態(tài)管理:
view:界面層,主要是UI
Logic:邏輯層,主要處理業(yè)務(wù)邏輯
State:狀態(tài)層,主要處理頁(yè)面所需數(shù)據(jù)狀態(tài)
Action:行為層,主要處理交互事件
Reducer:這個(gè)層級(jí),是專(zhuān)門(mén)用于處理數(shù)據(jù)變化的
Provider:是最為推薦的狀態(tài)管理庫(kù),對(duì)InheritedWidget進(jìn)行了上層封裝,解決原生setState方案的props臃腫、展示與邏輯耦合問(wèn)題;Provider將頁(yè)面分為業(yè)務(wù)和視圖兩層,并定義Notifier、Consumer兩個(gè)核心概念
Notifier負(fù)責(zé)實(shí)現(xiàn)業(yè)務(wù)邏輯,且在數(shù)據(jù)更新時(shí)發(fā)出通知。
Consumer負(fù)責(zé)實(shí)現(xiàn)界面邏輯,并在數(shù)據(jù)更新時(shí)更新自身,以及用戶(hù)交互時(shí)調(diào)用Notifier方法。
12.Flutter如何與原生Android,iOS進(jìn)行通信
Flutter通過(guò)PlatformChannel與原生進(jìn)行交互,總共有三種:
BasicMessageChannel:傳遞字符串和半結(jié)構(gòu)化信息;
MethodChannel:傳遞方法調(diào)用;一般就是MethodChannel.result;
EventChannel:傳遞數(shù)據(jù)流(event streams);
13.Flutter的熱重載
基于JIT編譯模式的代碼增量同步,總共分為五步:
掃描工程改動(dòng);增量編譯;推送更新;代碼合并;Widget重建;
所以并不會(huì)讓APP重新啟動(dòng),縮短時(shí)間;
14.Flutter布局
Row (行布局)
Column (列布局)
Container (容器)
ListView(類(lèi)似iOS中的UITableView):GlobalKey,通過(guò) key 去獲取到控件對(duì)象的 BuildContext(其實(shí)就是RenderObject);
15.Flutter集成聲網(wǎng)
在initState方法里初始化RtcEngine對(duì)象,通過(guò)initAgoraRtc和addAgoraEventHandlers,和joinChannel;
在回調(diào)中有加入頻道,離開(kāi)頻道,用戶(hù)加入頻道,第一次個(gè)視頻幀渲染回調(diào);
聊天相關(guān)的是單獨(dú)的createClient,通過(guò)AgoraRtmClient來(lái)管理用戶(hù)聊天等相關(guān)信息
-------------------------------------------------------------------------------------------------
Dart相關(guān)
1.Dart是類(lèi)型安全的語(yǔ)言,它會(huì)自動(dòng)做類(lèi)型轉(zhuǎn)換;并且會(huì)有靜態(tài)檢查和運(yùn)行時(shí)檢查;
所以它的維護(hù)性高,編譯器就可以顯示類(lèi)型錯(cuò)誤;
2.類(lèi)型
Number? String? Bool? List? Set? Map? Null