flutter 知識點總結(一)

文檔參考 https://zhuanlan.zhihu.com/p/102193331
請直接參考原文


1.Dart中的..表示什么意思?

Dart中的..表示 級聯操作符,為了方便配置而使用。...不同的是調用..后返回的this.而.返回的則是該方法的返回值。

2.Dart的作用域

Dart是沒有publicprivate關鍵字的,默認就是公開的,私有變量使用下劃線_開頭

3.Dart是不是單線程模型?是如何運行的?

  • Dart是單線程模型。簡單來說,Dart在單線程中是以消息循環機制來運行的,包含兩個任務隊列。一個是微任務隊列microtask queue,另一個叫做事件任務隊列event queue
  • flutter啟動后,消息循環機制也啟動了。首先按照先進先出的順序逐個執行微任務隊列中的數據,當微任務隊列中的數據執行完成后便開始執行事件隊列中的任務,事件任務執行完畢后再去執行微任務,如此循環往復,直到兩個隊列中的任務都為空。
  • 微任務隊列(microtask queue),表示一個短時間內就會完成的異步任務。它的優先級最高,高于event queue,只要隊列中還有任務,就可以一直霸占著事件循環。microtask queue添加的任務主要是由 Dart內部產生。
  • 事件隊列(event queue),包含所有的外來事件:I/O、mouse events、drawing events、timers、isolate之間的信息傳遞。
  • 因為 microtask queue 的優先級高于event queue ,所以如果 microtask queue有太多的微任務, 那么就可能會霸占住當前的event loop。從而對event queue中的觸摸、繪制等外部事件造成阻塞卡頓。
運行流程圖

4.Dart是如何實現多任務并行的

  • Dart實現多任務并行主要依賴dart的并發編程、異步和驅動機制。
  • 在dart中,一個Isolate對象其實就是一個Isolate執行環境的引用,一般來說我們都是通過當前的Isolate去控制其他的Isolate完成彼此之間的交互,而當我們想要創建一個新的Isolate可以使用Isolate.spawn方法獲取一個新的Isolate對象,兩個Isolate之間使用SendPort相互發送消息,而Isolate中也存在了一個與之對應ReceivePort接收消息用來處理,但是我們需要注意的是SendPortReceivePort在每一個Isolate都有一對,只有同一個Isolate中的ReceivePort才能接受當前類的SendPort發送的消息并且處理。

Isolate可以把它理解為Dart中的線程。但它又不同于線程,更恰當的說應該是微線程。它與線程最大的區別就是不能共享內存,因此也不存在鎖競爭問題,兩個Isolate完全是兩條獨立的執行線,且每個Isolate都有自己的事件循環,它們之間只能通過發送消息通信,所以它的資源開銷低于線程。

Isolate交互

5.說下Dart異步編程中的Future關鍵字?

在dart編程中,經常會使用Future來處理異步或者延時處理等任務操作。在dart的每一個isolate中,執行的優先級為:Main-MicroTask-EventQueue

6.說下Dart異步編程中的Stream數據流

  • 在 Flutter 中有兩種處理異步操作的方式 Future 和 Stream,Future 用于處理單個異步操作,Stream 用來處理連續的異步操作
  • Stream 是一個抽象類,用于表示一序列異步數據的源。它是一種產生連續事件的方式,可以生成數據事件或者錯誤事件,以及流結束時的完成事件。
  • 單訂閱流在發送完成事件之前只允許設置一個監聽器,并且只有在流上設置監聽器后才開始產生事件,取消監聽器后將停止發送事件。即使取消了第一個監聽器,也不允許在單訂閱流上設置其他的監聽器。廣播流則允許設置多個監聽器,也可以在取消上一個監聽器后再次添加新的監聽器。默認為單訂閱模式
  • Stream 有同步流和異步流之分。它們的區別在于同步流會在執行 add,addError 或 close 方法時立即向流的監聽器 StreamSubscription 發送事件,而異步流總是在事件隊列中的代碼執行完成后在發送事件。`

7. await for如何使用?

await for是用來不斷獲取stream流中的數據,然后執行循環體中的操作。它一般用在直到stream什么時候完成,并且必須等待傳遞完成后才能使用,不然會阻塞。

Stream<String> stream = new Stream<String>.fromIterable(['不開心', '面試', '沒', '過']);
main() async{
    await for(String s in stream){
    print(s);
  }
}

8.說下mixin機制?

  • dart為了支持多繼承引入mixin關鍵字。mixin定義的類不能有構造方法,這樣可以避免繼承多個類而產生的父類構造方法沖突。
  • mixins對象是類,mixins絕不是繼承,也不是接口,而是一種全新的特性,可以mixins多個類,mixins使用需要滿足一定條件。

9.介紹下flutter框架,以及優缺點

google退出的跨平臺UI框架,可以快速在Android、ios上構建應用

優點

  • 熱加載,保存后重載,模擬器立馬看見效果,相比原生編譯過程簡單
  • 一切皆為組件,實現了富有感染力的靈活界面設計;
  • 運行效率高

缺點

  • 不支持熱更新
  • Dart語言增加了學習難度

10.介紹下flutter的理念架構

flutter的理念架構

flutter自下而上分為EmbedderEngineFramework三層。

  • Embedder是操作系統適配層,實現了渲染Surface設置、線程設置,以及平臺插件等平臺相關特性的適配;
  • Engine層負責圖形繪制、文字排版和dart運行時。具有獨立虛擬機,正是由于他的存在,flutter可以運行在不同設備上
  • Framework是dart編寫的基礎視圖庫,包含動畫、圖形、手勢等功能,使用頻率最高的一層

11.flutter的EngineFramework作用

  • Framework是dart編寫的框架,實現了一系列基礎庫,包含MaterialCuptertino風格的界面,還有就是動畫、繪制、手勢等等;
  • Engine層是Skia 2D的繪圖引擎庫,其前身是個向量繪圖軟件,chromeandroid均采用Skia作為繪圖引擎層。skia是跨平臺的,所以可以被嵌入到flutter的sdk中。android自帶skia所以Flutter android SDKiOS sdk小很多

12.介紹下Widget、State、Context概念

  • Widget:在flutter'中一切皆為組件,可以將Widget想成一個可視化組件
  • Widget樹:Widget以樹結構進行組織。包含父Widget、子Widget
  • Context: Widget樹結構中某個Widget位置引用。一個context只屬于一個widget,他和widget一樣是鏈接在一起的,形成一個context樹
  • State:定義了StatefulWidget實例的行為,用于交互、干預widget行為和布局

13.簡述StatelessWidgetStatefulWidget

  • StatelessWidget 一旦創建就不關心任何變化,在下次構建前不會有任何變化。如TextRowContainer等。生命周期也簡單:初始化、build()渲染
  • StatefulWidget 生命周期內,該類所持有的數據可能會發生變化,這樣的數據被稱為State。如復選框、button等等。State與Context關聯,并且關聯是永久性的,State對象將永遠不會改變其Context。當state與context關聯時,state被視為已掛載。

14.StatefulWidget生命周期

生命周期
  • initState() : Widget初始化當前State,在當前方法中不能獲取到Context的,如果想獲取,可以試試Future.delayed
  • didChageDependencies()(1)initState() 后調用,(2)State對象依賴發生變化調用;系統語言、主題修改,系統也會通知調用
  • deactivate()當State被暫時從視圖樹種移除時會調用,頁面切換時也會調用
  • despose()Widget銷毀時調用
  • didUpdateWidget() Widget狀態發生變化時調用,新舊Widget的key、runtimeType不變時調用。也就是Widget.canUpdate=>true.
  • reassemble() 熱重載會被調用,在release下永遠不會被調用

創建并打開:initState->didChangeDependencies->build.
橫豎屏切換:didUpdateWidget->build 當前值保留
離開頁面:deactivate->dispose 重新進入init重新初始化
熱重載執行:reassemble->didUpdateWidget->build
調用setState->build

15.說下Widgets、RenderObjects和Elements的關系

  • Widget:僅用于存儲渲染所需要的信息
  • renderObject:負責管理布局、繪制等操作
  • Element: 控制樹上的實體,管理底層渲染樹
    Widget會被inflate(填充)到Element,并由Element管理底層渲染樹。Widget并不會直接管理狀態及渲染,而是通過state這個對象來管理狀態。flutetr創建Element可見樹,相對于Widget是可變的,通常用于開發中,我們不用操作 Element,而是由框架層實現內部邏輯。就如一個UI視圖樹中,可能包含多個TextWidget,但是放在內部視圖樹的視角,這些TextWidget都是填充到一個個獨立的Element中。Element會持有Widgets、RenderObjects的實例。記住,Widget只是一個配置,renderObject負責管理布局、繪制等操作。
    在第一個創建Widget的時候,會對應創建一個Element,然后將該元素插入到樹中。如果之后Widget發生了變化,則將其與舊的Widget進行比較,并且更新Element。重要的事Element不會被重建,只是更新而已。

16.什么是狀態管理,你了解那些狀態管理框架?

Flutter中的狀態和前端React中的狀態概念是一致的。React框架核心是組件化,應用由組件搭建而成,組件最重要的概念就是狀態,狀態是一個組件的UI數據模型,是組件渲染的數據依據。
Flutter的狀態分為全局狀態和局部狀態兩種。推薦使用Google退出的Provider

17.簡述Flutter的繪制流程

flutter繪制流程

Flutter只關心向GPU(圖形處理器)提供視圖數據,GPU的vsync(垂直同步)信號同步到UI線程,UI線程使用dart來構建抽象的視圖結構,這份數據結構在GPU線程進行圖層合成。,這些數據提供給skia引擎渲染為GPU數據,這些數據通過openGL或者Vulkan提供給過給GPU

18.簡述Flutter的線程管理模型

flutter Engine層的架構示意圖
  • 默認情況下,Flutter Engine層會創建一個lsolate,并且Dart代碼默認運行在這個主lsolate上。必要時可以使用spawnUrlspawn兩種方式創建新的lsolate,新創建的lsolate由flutter進行統一的管理
  • Flutter Engline自己不創建和管理線程,Flutter Engine線程的創建是由Embeder負責的。Embeder指的是將引擎移植到平臺的中間層代碼。
  • 在flutter架構中,Embeder提供四個Task Runner,每個Task Runner負責不同的任務,Flutter Engine不在乎Task Runner運行在哪個線程,但是它需要在線程整個生命周期中保持穩定。

19. Flutter是如何與原生Android、iOS進行通信的?

flutter 通過PlatformChannel與原生進行交互,其中PlatformChannel分為如下三種:

  • BasicMessageChannel : 用于傳遞字符串及半結構化信息
  • MethodChannel : 用于傳遞方法調用(method invocation)
  • EnentChannel:用于數據流event streams的通信

同時 Platform Channel 并非是線程安全的

20.簡述Flutter的熱重載

  • flutter的熱重載是基于JIT編譯模式的代碼增量同步。由于JIT屬于動態編譯,能夠將Dart代碼編程生成中間代碼,讓Dart VM在運行時解釋執行,因此可以實現動態更新中間代碼實現增量同步。
  • 熱重載流程可以分為5步,包括:掃描工程改動、增量編譯、推送更新、代碼合并、Widget重建。flutter在接收到代碼后,并不會讓APP重新啟動執行,而只會副廠Widget樹的重新繪制,因此可以保持改動前狀態。
  • 另一方面,由于涉及狀態的保存于恢復,涉及狀態兼容與狀態初始化場景,熱重載是無法支持的,如改動前后widget狀態無法兼容、全局變量與靜態屬性的更改、main方法里的更改、initState方法中的更改、枚舉和泛型的更改等
  • 可以發現,熱重載提高了UI的效率,非常適合寫界面樣式這樣返回查看修改效果的場景。但由于狀態保存機制限制,熱重載本身有一些無法支持的邊界
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容

  • flutter column row布局的列表自適應寬高mainAxisSize: MainAxisSize.mi...
    wayDevelop閱讀 1,741評論 0 6
  • Flutter 1 Flutter是什么? Flutter是谷歌的移動UI框架,可以快速在iOS和Andro...
    江河_ios閱讀 1,355評論 0 3
  • Dart 部分 其實學習過 JavaScript 或者 Java/Kotlin 的人,在學習 Dart 上幾乎是沒...
    Android高級工程師閱讀 1,662評論 0 10
  • Dart是基于事件循環機制的單線程模型 一條執行線上,同時且只能執行一個任務(事件),其他任務都必須在后面排隊等待...
    Hankkinn閱讀 953評論 0 1
  • 漸變的面目拼圖要我怎么拼? 我是疲乏了還是投降了? 不是不允許自己墜落, 我沒有滴水不進的保護膜。 就是害怕變得面...
    悶熱當乘涼閱讀 4,301評論 0 13