Flutter 問題集錦
Flutter ... 是什麼
- 級聯運算子。
可以讓你在一個物件上連續呼叫多個物件上的方法。
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是不是單執行緒模型,是如何執行的? (訊息佇列)
- Dart 在單執行緒中是以訊息迴圈機制來執行的,其中包含兩個任務佇列,一個是“微任務佇列” microtask queue,另一個叫做“事件佇列” event queue。
- 入口函式 main() 執行完後,訊息迴圈機制便啟動了。首先會按照先進先出的順序逐個執行微任務佇列中的任務,當所有微任務佇列執行完後便開始執行事件佇列中的任務,事件任務執行完畢後再去執行微任務,如此迴圈往復,生生不息。
如圖所示:
在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沒有共享記憶體的併發,沒有競爭的可能性所以不需要鎖,也就不用擔心死鎖的問題。
使用過Bloc嗎,說一下Bloc的使用過程
使用過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關鍵字
?. ?? ?=