Flutter 問題集錦

語言: CN / TW / HK

Flutter ... 是什麼

  1. 級聯運算子。

可以讓你在一個物件上連續呼叫多個物件上的方法。 querySelector('#confirm') // 獲取物件 (Get an object). ..text = 'Confirm' // 使用物件的成員 (Use its members). ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!')); 2. 級聯運算子的巢狀。

級聯運算子可以巢狀。 final addressBook = (AddressBookBuilder() ..name = 'jenny' ..email = '[email protected]' ..phone = (PhoneNumberBuilder() ..number = '415-555-0100' ..label = 'home') .build()) .build();

dart的作用域

Dart 沒有 「public」「private」等關鍵字,預設就是公開的,私有變數使用 下劃線 _開頭。

dart是不是單執行緒模型,是如何執行的? (訊息佇列)

  1. Dart 在單執行緒中是以訊息迴圈機制來執行的,其中包含兩個任務佇列,一個是“微任務佇列” microtask queue,另一個叫做“事件佇列” event queue。
  2. 入口函式 main() 執行完後,訊息迴圈機制便啟動了。首先會按照先進先出的順序逐個執行微任務佇列中的任務,當所有微任務佇列執行完後便開始執行事件佇列中的任務,事件任務執行完畢後再去執行微任務,如此迴圈往復,生生不息。

如圖所示:

image.png

在flutter裡streams是什麼?有幾種streams?有什麼場景用到它?

Stream 用來處理連續的非同步操作,Stream 是一個抽象類,用於表示一序列非同步資料的源。它是一種產生連續事件的方式,可以生成資料事件或者錯誤事件,以及流結束時的完成事件 Stream 分單訂閱流和廣播流。 網路狀態的監控

簡單說一下在flutter裡async和await?

await的出現會把await之前和之後的程式碼分為兩部分,await並不像字面意思所表示的程式執行到這裡就阻塞了,而是立刻結束當前函式的執行並返回一個Future,函式內剩餘程式碼通過排程非同步執行。 async是和await搭配使用的,await只在async函式中出現。在async 函式裡可以沒有await或者有多個await。

future 和steam有什麼不一樣?

在 Flutter 中有兩種處理非同步操作的方式 Future 和 Stream,Future 用於處理單個非同步操作,Stream 用來處理連續的非同步操作。

怎麼理解Isolate?

isolate是Dart對actor併發模式的實現。 isolate是有自己的記憶體和單執行緒控制的執行實體。isolate本身的意思是“隔離”,因為isolate之間的記憶體在邏輯上是隔離的。isolate中的程式碼是按順序執行的,任何Dart程式的併發都是執行多個isolate的結果。因為Dart沒有共享記憶體的併發,沒有競爭的可能性所以不需要鎖,也就不用擔心死鎖的問題。

dart非同步

使用過Bloc嗎,說一下Bloc的使用過程

bloc模式解析

使用過Getx嗎?說一下Getx能幹什麼?

getx文件

Flutter 能播放視訊嗎?假如說要播放視訊你會採取什麼方式?

說一下mixin

首先mixin是一個定義類的關鍵字。直譯出來是混入,混合的意思 Dart為了支援多重繼承,引入了mixin關鍵字,它最大的特殊處在於: mixin定義的類不能有構造方法,這樣可以避免繼承多個類而產生的父類構造方法衝突。

就是將implement替換成了with,abstract class替換成了mixin嘛,也太簡單了。但仔細一看,我們發現mixin裡有方法的具體實現,這樣可以避免介面的方法必須在子類實現從而導致的程式碼冗餘(Java 8通過關鍵字default也可以做到這一點)問題。簡而言之,mixin相對於介面能夠更好的避免程式碼冗餘,使程式碼更加集中。

Flutter 元件的生命週期

StatelessWidget

生命週期只有一個,就是build - buid build 是用來建立 Widget 的,但因為 build 在每次介面重新整理的時候都會呼叫, 所以不要在 build 裡寫業務邏輯,可以把業務邏輯寫到你的 StatelessWidget 的建構函式裡。

StatefullWidget

StatefulWidget 的生命週期比較複雜,依次為:

  • createState

createState 是 StatefulWidget 裡建立 State 的方法,當要建立新的 StatefulWidget 的時候,會立即執行 createState,而且只執行一次,createState 必須要實現:

  • initState

前面的 createState 是在建立 StatefulWidget 的時候會呼叫,initState 是 StatefulWidget 建立完後呼叫的第一個方法,而且只執行一次,類似於 Android 的 onCreate、iOS 的 viewDidLoad(),所以在這裡 View 並沒有渲染,但是這時 StatefulWidget 已經被載入到渲染樹裡了,這時 StatefulWidget 的 mount的值會變為 true,直到 dispose呼叫的時候才會變為 false。可以在 initState裡做一些初始化的操作。 在 override initState的時候必須要呼叫 super.initState():

  • didChangeDependencies

當 StatefulWidget 第一次建立的時候,didChangeDependencies方法會在 initState方法之後立即呼叫,之後當 StatefulWidget 重新整理的時候,就不會呼叫了,除非你的 StatefulWidget 依賴的 InheritedWidget 發生變化之後,didChangeDependencies才會呼叫,所以 didChangeDependencies有可能會被呼叫多次。

這個函式會緊跟在initState之後呼叫,並且可以呼叫BuildContext.inheritFromWidgetOfExactType,那麼BuildContext.inheritFromWidgetOfExactType的使用場景是什麼呢?最經典的應用場景是

  • build

在 StatefulWidget 第一次建立的時候,build方法會在 didChangeDependencies方法之後立即呼叫,另外一種會呼叫 build方法的場景是,每當 UI 需要重新渲染的時候(setState觸發),build都會被呼叫,所以 build會被多次呼叫,然後 返回要渲染的 Widget。千萬不要在 build裡做除了建立 Widget 之外的操作,因為這個會影響 UI 的渲染效率

  • addPostFrameCallback

addPostFrameCallback是 StatefulWidge 渲染結束的回撥,只會被呼叫一次,之後 StatefulWidget 需要重新整理 UI 也不會被呼叫,addPostFrameCallback的使用方法是在 initState裡添加回調: import 'package:flutter/scheduler.dart'; @override void initState() { super.initState(); SchedulerBinding.instance.addPostFrameCallback((_) => {}); } - didUpdateWidget 祖先節點rebuild widget時呼叫 .當元件的狀態改變的時候就會呼叫didUpdateWidget.(可能會呼叫多次)

理論上setState的時候會呼叫,但我實際操作的時候發現只是做setState的操作的時候沒有呼叫這個方法。而在我改變程式碼hot reload時候會呼叫 didUpdateWidget 並執行 build…

實際上這裡flutter框架會建立一個新的Widget,繫結本State,並在這個函式中傳遞老的Widget。這個函式一般用於比較新、老Widget,看看哪些屬性改變了,並對State做一些調整。

需要注意的是,涉及到controller的變更,需要在這個函式中移除老的controller的監聽,並建立新controller的監聽。

  • deactivate

當要將 State 物件從渲染樹中移除的時候,就會呼叫 deactivate生命週期,這標誌著 StatefulWidget 將要銷燬,但是有時候 State 不會被銷燬,而是重新插入到渲染樹種。 - dispose

當 View 不需要再顯示,從渲染樹中移除的時候,State 就會永久的從渲染樹中移除,就會呼叫 dispose生命週期,這時候就可以在 dispose裡做一些取消監聽、動畫的操作,和 initState是相反的。

dart擴充套件

如何監聽FlutterApp是在前臺還是後臺?

AppLifecycleState 就是 App 的生命週期,有: - resumed - inactive - paused - suspending

如果想要知道 Flutter App 的生命週期,例如 Flutter 是在前臺還是在後臺,就需要使用到 WidgetsBindingObserver了,使用方法如下:

1.State 的類 mix WidgetsBindingObserver: class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver { ... } 2.在 State 的 initState裡新增監聽: @override void initState(){ super.initState(); WidgetsBinding.instance.addObserver(this); } 3.在 State 的 dispose裡移除監聽: @override void dispose() { // TODO: implement dispose super.dispose(); WidgetsBinding.instance.removeObserver(this); } 4. 在 State 裡 override didChangeAppLifecycleState @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); if (state == AppLifecycleState.paused) { // went to Background } if (state == AppLifecycleState.resumed) { // came back to Foreground } }

Flutter如何與安卓或IOS通訊?

Flutter 通過 PlatformChannel 與原生進行互動,其中 PlatformChannel 分為三種:

BasicMessageChannel:用於傳遞字串和半結構化的資訊。 MethodChannel:用於傳遞方法呼叫。Flutter主動呼叫Native的方法,並獲取相應的返回值。 EventChannel:用於資料流(event streams)的通訊。

main()和runApp()函式在flutter的作用分別是什麼?有什麼關係嗎?

  • main函式是類似於java語言的程式執行入口函式
  • runApp函式是渲染根widget樹的函式
  • 一般情況下runApp函式會在main函式裡執行

(提高)Hot Restart 和 Hot Reload 有什麼區別嗎?

Hot Reload比Hot Restart快,Hot Reload會編譯我們檔案裡新加的程式碼併發送給dart虛擬機器,dart會更新widgets來改變UI,而Hot Restart會讓dart 虛擬機器重新編譯應用。另一方面也是因為這樣, Hot Reload會保留之前的state,而Hot Restart回你重置所有的state回到初始值。

(提高)介紹下Widget、State、Context 概念

Widget:在Flutter中,幾乎所有東西都是Widget。將一個Widget想象為一個視覺化的元件(或與應用視覺化方面互動的元件),當你需要構建與佈局直接或間接相關的任何內容時,你正在使用Widget。

Widget樹:Widget以樹結構進行組織。包含其他Widget的widget被稱為父Widget(或widget容器)。包含在父widget中的widget被稱為子Widget。

Context:僅僅是已建立的所有Widget樹結構中的某個Widget的位置引用。簡而言之,將context作為widget樹的一部分,其中context所對應的widget被新增到此樹中。一個context只從屬於一個widget,它和widget一樣是連結在一起的,並且會形成一個context樹。

State:定義了StatefulWidget例項的行為,它包含了用於”互動/干預“Widget資訊的行為和佈局。應用於State的任何更改都會強制重建Widget。

有沒有做過混合開發?混合開發分為哪幾種方式。

混合開發中如何對aar庫進行依賴的?

有沒有搭建過dart私服

Dart中var與dynamic的區別

使用var來宣告變數,dart會在編譯階段自動推匯出型別。而dynamic不在編譯期間做型別檢查而是在執行期間做型別校驗。

const和final的區別

const 的值在編譯期確定,final 的值在運⾏時確定。

dart中空安全是如何處理的?相關操作符有哪些? late關鍵字

?. ?? ?=

如何設定元件寬度為最大?

Expended元件需要跟什麼配合才能發揮作用?