1、Dart中var 與 dynamic的區(qū)別
2、const和final的區(qū)別
3、Dart中 ?? 與 ??= 的區(qū)別
3、 什么是flutter里的key? 有什么用?
key是Widgets,Elements和SemanticsNodes的標(biāo)識(shí)符。
key有LocalKey 和 GlobalKey兩種。
LocalKey 如果要修改集合中的控件的順序或數(shù)量。GlobalKey允許 Widget 在應(yīng)用中的 任何位置更改父級(jí)而不會(huì)丟失 State。
4、Flutter中的GlobalKey是什么,有什么作用
GlobalKey可以獲取到對應(yīng)的Widget的State對象
需求:當(dāng)我們頁面內(nèi)容很多時(shí),而需要改變的內(nèi)容只有很少的一部分且在樹的底層的時(shí) 候,我們?nèi)绾稳?shí)現(xiàn)增量更新?
通常情況下有兩種方式,第一種是通過方法的回調(diào),去實(shí)現(xiàn)數(shù)據(jù)更新,第二種是通過GlobalKey,在StatelessWidget引用StatefulWidget。
4、1main()和runApp()函數(shù)在flutter的作用分別是什么?有什么關(guān)系嗎?
* main函數(shù)是類似于java語言的程序運(yùn)行入口函數(shù)
* runApp函數(shù)是渲染根widget樹的函數(shù)
* 一般情況下runApp函數(shù)會(huì)在main函數(shù)里執(zhí)行
5、什么是widget? 在flutter里有幾種類型的widget?分別有什么區(qū)別?能分別說一下生命周期嗎?
widget在flutter里基本是一些UI組件
有兩種類型的widget,分別是statefulWidget 和 statelessWidget兩種
statelessWidget不會(huì)自己重新構(gòu)建自己,但是statefulWidget會(huì)
statelessWidget生命周期:
1. 構(gòu)造函數(shù)
2. build方法
StatefulWidget生命周期:
1. widget的構(gòu)造方法
2. widget的createState方法
3. state的構(gòu)造方法
4. state的initState方法(重寫該方法時(shí),必須要先調(diào)用super. initState())
5. didChangeDependencies方法,分兩種情況:
* 調(diào)用initState方法后,會(huì)調(diào)用該方法
* 從其他widget中依賴一些數(shù)據(jù)發(fā)生改變時(shí),比如用InheritedWidget,provider來監(jiān)聽數(shù)據(jù)的改變
6. state的build方法(當(dāng)調(diào)用setState方法,會(huì)重新調(diào)用build進(jìn)行渲染)
7. state的deactivate方法(當(dāng)state被暫時(shí)從視圖移除的時(shí)候會(huì)調(diào)用,頁面push走、pop回來的時(shí)候都會(huì)調(diào)用。因?yàn)閜ush、pop會(huì)改變widget在視圖樹位置,需要先移除再添加。重寫該方法時(shí),必須要先調(diào)用super.deactivate())
8. state的dispose方法。頁面被銷毀的時(shí)候調(diào)用,如:pop操作。通常情況下,自己的釋放邏輯放在super.dispose()之前,先操作子類在操作父類。
5、簡單說一下在Flutter里async和await?
await的出現(xiàn)會(huì)把a(bǔ)wait之前和之后的代碼分為兩部分,await并不像字面意思所表示的程序運(yùn)行到這里就阻塞了,而是立刻結(jié)束當(dāng)前函數(shù)的執(zhí)行并返回一個(gè)Future,函數(shù)內(nèi)剩余代碼通過調(diào)度異步執(zhí)行。
async是和await搭配使用的,await只在async函數(shù)中出現(xiàn)。在async 函數(shù)里可以沒有await或者有多個(gè)await。
6、future和steam有什么不一樣?
在 Flutter 中有兩種處理異步操作的方式 Future 和 Stream,F(xiàn)uture 用于處理單個(gè)異步操作,Stream 用來處理連續(xù)的異步操作。
8、flutter中Widget、Element、RenderObject、Layer都有什么關(guān)系?
首先看一下這幾個(gè)對象的含義及作用。
* Widget:僅用于存儲(chǔ)渲染所需要的信息。
* RenderObject:負(fù)責(zé)管理布局、繪制等操作。
* Element:才是這顆巨大的控件樹上的實(shí)體。
Widget會(huì)被inflate(填充)到Element,并由Element管理底層渲染樹。Widget并不會(huì)直接管理狀態(tài)及渲染,而是通過State這個(gè)對象來管理狀態(tài)。Flutter創(chuàng)建Element的可見樹,相對于Widget來說,是可變的,通常界面開發(fā)中,我們不用直接操作Element,而是由框架層實(shí)現(xiàn)內(nèi)部邏輯。就如一個(gè)UI視圖樹中,可能包含有多個(gè)TextWidget(Widget被使用多次),但是放在內(nèi)部視圖樹的視角,這些TextWidget都是填充到一個(gè)個(gè)獨(dú)立的Element中。Element會(huì)持有renderObject和widget的實(shí)例。記住,Widget 只是一個(gè)配置,RenderObject 負(fù)責(zé)管理布局、繪制等操作。
在第一次創(chuàng)建 Widget 的時(shí)候,會(huì)對應(yīng)創(chuàng)建一個(gè) Element, 然后將該元素插入樹中。如果之后 Widget 發(fā)生了變化,則將其與舊的 Widget 進(jìn)行比較,并且相應(yīng)地更新 Element。重要的是,Element 不會(huì)被重建,只是更新而已。
9、簡述state的生命周期
10、簡述flutter中自定義View流程?
11、flutter_boost的優(yōu)缺點(diǎn),內(nèi)部實(shí)現(xiàn)
12、flutter的渲染機(jī)制
Flutter只關(guān)心向 GPU提供視圖數(shù)據(jù),GPU的 VSync信號(hào)同步到 UI線程,UI線程使用 Dart來構(gòu)建抽象的視圖結(jié)構(gòu),這份數(shù)據(jù)結(jié)構(gòu)在 GPU線程進(jìn)行圖層合成,視圖數(shù)據(jù)提供給 Skia引擎渲染為 GPU數(shù)據(jù),這些數(shù)據(jù)通過 OpenGL或者 Vulkan提供給 GPU。
13、flutter和nativi的優(yōu)缺點(diǎn)
14、flutter支不支持 120hz
16、狀態(tài)管理熟悉哪些
Flutter中的狀態(tài)和前端React中的狀態(tài)概念是一致的。React框架的核心思想是組件化,應(yīng)用由組件搭建而成,組件最重要的概念就是狀態(tài),狀態(tài)是一個(gè)組件的UI數(shù)據(jù)模型,是組件渲染時(shí)的數(shù)據(jù)依據(jù)。
Flutter的狀態(tài)可以分為全局狀態(tài)和局部狀態(tài)兩種。常用的狀態(tài)管理有ScopedModel、BLoC、Redux / FishRedux和Provider。
17、多線程怎么處理
18、flutter中大圖片上傳
19、await for 如何使用
await for是不斷獲取stream流中的數(shù)據(jù),然后執(zhí)行循環(huán)體中的操作。它一般用在直到stream什么時(shí)候完成,并且必須等待傳遞完成之后才能使用,不然就會(huì)一直阻塞。
20、Stream有兩種訂閱模式
Stream 用來處理連續(xù)的異步操作,Stream 是一個(gè)抽象類,用于表示一系列異步數(shù)據(jù)的源。它是一種產(chǎn)生連續(xù)事件的方式,可以生成數(shù)據(jù)事件或者錯(cuò)誤事件,以及流結(jié)束時(shí)的完成事件
Stream 分單訂閱流和廣播流。
網(wǎng)絡(luò)狀態(tài)的監(jiān)控
21、flutter butild 方法中的 BuildContext 具體是什么東西
BuildContext底層原理實(shí)現(xiàn)實(shí)際上就是Element of(context)原理,其實(shí)就是通過調(diào)用BuildContext各種實(shí)現(xiàn)方法遍歷widget tree和Element tree 從而獲取到指定的對象來達(dá)到數(shù)據(jù)共享的目的
【【Flutter核心類分析】深入理解BuildContext | 航行學(xué)園】http://www.voycn.com/article/flutterhexinleifenxi-shenrulijiebuildcontext
22、flutter 打包成web 移動(dòng)端 桌面端的過程是怎么樣的
23、dart是值傳遞還是引用傳遞
值傳遞
24、dart是弱引用還是強(qiáng)引用
強(qiáng)引用
25、get set方法實(shí)現(xiàn)
26、Flutter 是如何與原生Android、iOS進(jìn)行通信的?
Flutter 通過 PlatformChannel 與原生進(jìn)行交互,其中 PlatformChannel 分為三種:
* BasicMessageChannel :用于傳遞字符串和半結(jié)構(gòu)化的信息。
* MethodChannel :用于傳遞方法調(diào)用(method invocation)。
* EventChannel : 用于數(shù)據(jù)流(event streams)的通信。
同時(shí) Platform Channel 并非是線程安全的
27、簡述Flutter 的熱重載
Flutter 的熱重載是基于 JIT 編譯模式的代碼增量同步。由于 JIT 屬于動(dòng)態(tài)編譯,能夠?qū)?Dart 代碼編譯成生成中間代碼,讓 Dart VM 在運(yùn)行時(shí)解釋執(zhí)行,因此可以通過動(dòng)態(tài)更新中間代碼實(shí)現(xiàn)增量同步。
熱重載的流程可以分為 5 步,包括:掃描工程改動(dòng)、增量編譯、推送更新、代碼合并、Widget 重建。Flutter 在接收到代碼變更后,并不會(huì)讓 App 重新啟動(dòng)執(zhí)行,而只會(huì)觸發(fā) Widget 樹的重新繪制,因此可以保持改動(dòng)前的狀態(tài),大大縮短了從代碼修改到看到修改產(chǎn)生的變化之間所需要的時(shí)間。
另一方面,由于涉及到狀態(tài)的保存與恢復(fù),涉及狀態(tài)兼容與狀態(tài)初始化的場景,熱重載是無法支持的,如改動(dòng)前后 Widget 狀態(tài)無法兼容、全局變量與靜態(tài)屬性的更改、main 方法里的更改、initState 方法里的更改、枚舉和泛型的更改等。
可以發(fā)現(xiàn),熱重載提高了調(diào)試 UI 的效率,非常適合寫界面樣式這樣需要反復(fù)查看修改效果的場景。但由于其狀態(tài)保存的機(jī)制所限,熱重載本身也有一些無法支持的邊界。
28、怎么理解Isolate?
isolate是Dart對actor并發(fā)模式的實(shí)現(xiàn)。 isolate是有自己的內(nèi)存和單線程控制的運(yùn)行實(shí)體。isolate本身的意思是“隔離”,因?yàn)閕solate之間的內(nèi)存在邏輯上是隔離的。isolate中的代碼是按順序執(zhí)行的,任何Dart程序的并發(fā)都是運(yùn)行多個(gè)isolate的結(jié)果。因?yàn)镈art沒有共享內(nèi)存的并發(fā),沒有競爭的可能性所以不需要鎖,也就不用擔(dān)心死鎖的問題
29、Dart 的作用域
Dart 沒有 「public」「private」等關(guān)鍵字,默認(rèn)就是公開的,私有變量使用下劃線 _開頭。
30、Dart 當(dāng)中的 「..」表示什么意思?
Dart 當(dāng)中的 「..」意思是 「級(jí)聯(lián)操作符」,為了方便配置而使用?!?.」和「.」不同的是 調(diào)用「..」后返回的相當(dāng)于是 this,而「.」返回的則是該方法返回的值 。
31、Dart 是不是單線程模型?是如何運(yùn)行的?
Dart 是單線程模型,運(yùn)行的的流程如下圖。
簡單來說,Dart 在單線程中是以消息循環(huán)機(jī)制來運(yùn)行的,包含兩個(gè)任務(wù)隊(duì)列,一個(gè)是“微任務(wù)隊(duì)列” microtask queue,另一個(gè)叫做“事件隊(duì)列” event queue。
當(dāng)Flutter應(yīng)用啟動(dòng)后,消息循環(huán)機(jī)制便啟動(dòng)了。首先會(huì)按照先進(jìn)先出的順序逐個(gè)執(zhí)行微任務(wù)隊(duì)列中的任務(wù),當(dāng)所有微任務(wù)隊(duì)列執(zhí)行完后便開始執(zhí)行事件隊(duì)列中的任務(wù),事件任務(wù)執(zhí)行完畢后再去執(zhí)行微任務(wù),如此循環(huán)往復(fù),生生不息。
32、Dart 是如何實(shí)現(xiàn)多任務(wù)并行的?
前面說過, Dart 是單線程的,不存在多線程,那如何進(jìn)行多任務(wù)并行的呢?其實(shí),Dart的多線程和前端的多線程有很多的相似之處。Flutter的多線程主要依賴Dart的并發(fā)編程、異步和事件驅(qū)動(dòng)機(jī)制。
簡單的說,在Dart中,一個(gè)Isolate對象其實(shí)就是一個(gè)isolate執(zhí)行環(huán)境的引用,一般來說我們都是通過當(dāng)前的isolate去控制其他的isolate完成彼此之間的交互,而當(dāng)我們想要?jiǎng)?chuàng)建一個(gè)新的Isolate可以使用Isolate.spawn方法獲取返回的一個(gè)新的isolate對象,兩個(gè)isolate之間使用SendPort相互發(fā)送消息,而isolate中也存在了一個(gè)與之對應(yīng)的ReceivePort接受消息用來處理,但是我們需要注意的是,ReceivePort和SendPort在每個(gè)isolate都有一對,只有同一個(gè)isolate中的ReceivePort才能接受到當(dāng)前類的SendPort發(fā)送的消息并且處理。
33、說一下Dart異步編程中的 Future關(guān)鍵字?
前面說過,Dart 在單線程中是以消息循環(huán)機(jī)制來運(yùn)行的,其中包含兩個(gè)任務(wù)隊(duì)列,一個(gè)是“微任務(wù)隊(duì)列” microtask queue,另一個(gè)叫做“事件隊(duì)列” event queue。
在Java并發(fā)編程開發(fā)中,經(jīng)常會(huì)使用Future來處理異步或者延遲處理任務(wù)等操作。而在Dart中,執(zhí)行一個(gè)異步任務(wù)同樣也可以使用Future來處理。在 Dart 的每一個(gè) Isolate 當(dāng)中,執(zhí)行的優(yōu)先級(jí)為 : Main > MicroTask > EventQueue。
34、說一下 mixin機(jī)制?
mixin 是Dart 2.1 加入的特性,以前版本通常使用abstract class代替。簡單來說,mixin是為了解決繼承方面的問題而引入的機(jī)制,Dart為了支持多重繼承,引入了mixin關(guān)鍵字,它最大的特殊處在于: mixin定義的類不能有構(gòu)造方法,這樣可以避免繼承多個(gè)類而產(chǎn)生的父類構(gòu)造方法沖突。
mixins的對象是類,mixins絕不是繼承,也不是接口,而是一種全新的特性,可以mixins多個(gè)類,mixins的使用需要滿足一定條件。
35、介紹下Flutter的FrameWork層和Engine層,以及它們的作用
Flutter的FrameWork層是用Dart編寫的框架(SDK),它實(shí)現(xiàn)了一套基礎(chǔ)庫,包含Material(Android風(fēng)格UI)和Cupertino(iOS風(fēng)格)的UI界面,下面是通用的Widgets(組件),之后是一些動(dòng)畫、繪制、渲染、手勢庫等。這個(gè)純 Dart實(shí)現(xiàn)的 SDK被封裝為了一個(gè)叫作 dart:ui的 Dart庫。我們在使用 Flutter寫 App的時(shí)候,直接導(dǎo)入這個(gè)庫即可使用組件等功能。
Flutter的Engine層是Skia 2D的繪圖引擎庫,其前身是一個(gè)向量繪圖軟件,Chrome和 Android均采用 Skia作為繪圖引擎。Skia提供了非常友好的 API,并且在圖形轉(zhuǎn)換、文字渲染、位圖渲染方面都提供了友好、高效的表現(xiàn)。Skia是跨平臺(tái)的,所以可以被嵌入到 Flutter的 iOS SDK中,而不用去研究 iOS閉源的 Core Graphics / Core Animation。Android自帶了 Skia,所以 Flutter Android SDK要比 iOS SDK小很多。
36、簡述Flutter的線程管理模型
默認(rèn)情況下,F(xiàn)lutter Engine層會(huì)創(chuàng)建一個(gè)Isolate,并且Dart代碼默認(rèn)就運(yùn)行在這個(gè)主Isolate上。必要時(shí)可以使用spawnUri和spawn兩種方式來創(chuàng)建新的Isolate,在Flutter中,新創(chuàng)建的Isolate由Flutter進(jìn)行統(tǒng)一的管理。事實(shí)上,F(xiàn)lutter Engine自己不創(chuàng)建和管理線程,F(xiàn)lutter Engine線程的創(chuàng)建和管理是Embeder負(fù)責(zé)的,Embeder指的是將引擎移植到平臺(tái)的中間層代碼,F(xiàn)lutter Engine層的架構(gòu)示意圖如下圖所示。
在Flutter的架構(gòu)中,Embeder提供四個(gè)Task Runner,分別是Platform Task Runner、UI Task Runner Thread、GPU Task Runner和IO Task Runner,每個(gè)Task Runner負(fù)責(zé)不同的任務(wù),F(xiàn)lutter Engine不在乎Task Runner運(yùn)行在哪個(gè)線程,但是它需要線程在整個(gè)生命周期里面保持穩(wěn)定。
37、介紹下Flutter的理念架構(gòu)
由上圖可知,F(xiàn)lutter框架自下而上分為Embedder、Engine和Framework三層。其中,Embedder是操作系統(tǒng)適配層,實(shí)現(xiàn)了渲染 Surface設(shè)置,線程設(shè)置,以及平臺(tái)插件等平臺(tái)相關(guān)特性的適配;Engine層負(fù)責(zé)圖形繪制、文字排版和提供Dart運(yùn)行時(shí),Engine層具有獨(dú)立虛擬機(jī),正是由于它的存在,F(xiàn)lutter程序才能運(yùn)行在不同的平臺(tái)上,實(shí)現(xiàn)跨平臺(tái)運(yùn)行;Framework層則是使用Dart編寫的一套基礎(chǔ)視圖庫,包含了動(dòng)畫、圖形繪制和手勢識(shí)別等功能,是使用頻率最高的一層。
38. Future和Isolate有什么區(qū)別?
future是異步編程,調(diào)用本身立即返回,并在稍后的某個(gè)時(shí)候執(zhí)行完成時(shí)再獲得返回結(jié)果。在普通代碼中可以使用await 等待一個(gè)異步調(diào)用結(jié)束。
isolate是并發(fā)編程,Dartm有并發(fā)時(shí)的共享狀態(tài),所有Dart代碼都在isolate中運(yùn)行,包括最初的main()。每個(gè)isolate都有它自己的堆內(nèi)存,意味著其中所有內(nèi)存數(shù)據(jù),包括全局?jǐn)?shù)據(jù),都僅對該isolate可見,它們之間的通信只能通過傳遞消息的機(jī)制完成,消息則通過端口(port)收發(fā)。isolate只是一個(gè)概念,具體取決于如何實(shí)現(xiàn),比如在Dart VM中一個(gè)isolate可能會(huì)是一個(gè)線程,在Web中可能會(huì)是一個(gè)Web Worker。
39、什么是Navigator? MaterialApp做了什么?
Navigator是在Flutter中負(fù)責(zé)管理維護(hù)頁面堆棧的導(dǎo)航器。MaterialApp在需要的時(shí)候,會(huì)自動(dòng)為我們創(chuàng)建Navigator。Navigator.of(context),會(huì)使用context來向上遍歷Element樹,找到MaterialApp提供的_NavigatorState再調(diào)用其push/pop方法完成導(dǎo)航操作。