1嚎杨、Dart是什么? 和Flutter是什么關(guān)系?
Dart是Google開發(fā)的一種面向?qū)ο蟮挠嬎銠C(jī)編程語言,和Java類似
Flutter 是 Google 開源的 UI 工具包,幫助開發(fā)者通過一套代碼庫高效構(gòu)建多平臺精美應(yīng)用,支持移動晴楔、Web载矿、桌面和嵌入式平臺
Dart是flutter的程序開發(fā)語言
2. main()和runApp()函數(shù)在flutter的作用分別是什么漆羔?有什么關(guān)系嗎?
main函數(shù)是類似于java語言的程序運(yùn)行入口函數(shù)
runApp函數(shù)是渲染根widget樹的函數(shù)
一般情況下runApp函數(shù)會在main函數(shù)里執(zhí)行
3. 什么是widget? 在flutter里有幾種類型的widget剿干?分別有什么區(qū)別?能分別說一下生命周期嗎?
Widget在flutter里基本是一些UI組件,和
在 Flutter 中怕磨,有兩類常用的 Widget:
- 無狀態(tài)的 StatelessWidget
- 有狀態(tài)的 StatefulWidget
在開發(fā)過程中喂饥,我們經(jīng)常需要繼承它們兩來實現(xiàn)自己的 Widget。
A肠鲫、無狀態(tài)的StatelessWidget
如果你的控件一旦顯示员帮,就不需要再做任何的變更,那么你應(yīng)該使用 StatelessWidget导饲。
實現(xiàn)一個自己的 StatelessWidget 很簡單捞高。
當(dāng)你看到下面這個例子??時,你就知道它有多簡單了渣锦。
class PageWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return _buildBody(context);
}
Widget _buildBody(BuildContext context){
return Container(
…
);
}
B硝岗、有狀態(tài)的StatefulWidget
它可以改變界面的狀態(tài),比如顯示的文字Text
、選中狀態(tài)CheckBox
Switch
等
我們之所以可以改變狀態(tài)是因為setState
,當(dāng)調(diào)用setState
后袋毙,就會觸發(fā) StatefulWidget 的視圖樹重建型檀。
setState((){
// 更新狀態(tài)、數(shù)據(jù)
})
因此娄猫,當(dāng)我們需要一個可交互的贱除,即能根據(jù)用戶操作或數(shù)據(jù)變化而改變視圖的 Widget 時,那就得用上 StatefulWidget 了媳溺。
周期
State的生命周期和StatefulWidget不同,當(dāng)StatefulWidget的狀態(tài)改變之后就會被重建,但是State不會改變,但是 StatefulWidget在View樹中移除再插入又會生成新的State.
總體介紹一下生命周期,大致可以看成三個階段:
- 初始化 (插入渲染樹??)
- 狀態(tài)改變 (在渲染樹中存在)
- 銷毀 (從渲染樹中移除)
生命周期詳解
initState
當(dāng)插入渲染樹的時候調(diào)用,這個函數(shù)在生命周期中只調(diào)用一次. 這里可以做一些初始化的工作,比如初始化State的變量
didChangeDependencies
這個函數(shù)會緊跟在initState之后調(diào)用,并且可以調(diào)用BuildContext.inheritFromWidgetOfExactType, 那么BuildContext.inheritFromWidgetOfExactType的使用場景是什么呢?
static TabController of(BuildContext context) {
final _TabControllerScope scope = context.inheritFromWidgetOfExactType(_TabControllerScope);
return scope?.controller;
}
實際上就是調(diào)用BuildContext.inheritFromWidgetOfExactType,也就是說在didChangeDependencies中,可以跨組件拿到數(shù)據(jù)
didUpdateWidget
當(dāng)組件的狀態(tài)改變的時候就會調(diào)用didUpdateWidget, 比如調(diào)用setState,
實際flutter框架會創(chuàng)建一個新的Widget綁定State,并在函數(shù)中傳遞老的Widget.
這個函數(shù)一般用于比較新、老Widget,看看哪些屬性改變了,并對State做一些調(diào)整.
需要注意的是涉及到controller的變更,需要在這個函數(shù)中移除老的controller的監(jiān)聽,并創(chuàng)建新controller.
deactivate
在dispoes之前,會調(diào)用這個函數(shù)
dispose
一旦到這個階段,組件就會被銷毀,這個函數(shù)一般會移除監(jiān)聽,清理環(huán)境
總結(jié)
階段 | 調(diào)用次數(shù) |
---|---|
構(gòu)造函數(shù) | 1 |
initState | 1 |
didChangeDependencies | >=1 |
didUpdateWidget | >=1 |
deactivate | >=1 |
dispose | 1 |
各方解釋
- initState: 插入渲染樹時調(diào)用只調(diào)用一次, widget創(chuàng)建執(zhí)行的第一個方法, 可以再里面初始化一些數(shù)據(jù),以及綁定控制器
- didChangeDependencies: 當(dāng)State對象的依賴發(fā)生變化時被調(diào)用
- build: 它主要用戶構(gòu)建Widget字樹的,調(diào)用次數(shù):多次,初始化之后開始繪制界面,當(dāng)調(diào)用setState觸發(fā)的時候會再次被調(diào)用
- deactivate: 當(dāng)State被暫時從視圖樹中移除時,會調(diào)用這個函數(shù).
頁面切換時也會調(diào)用它,因為此時State在視圖樹中的位置發(fā)送了變化,需要先暫時移除后添加 - dispose: 當(dāng)State對象從樹中被永久移除時調(diào)用; 通常在此回調(diào)中釋放資源.
- reassemble: 此回調(diào)是為了專門開發(fā)調(diào)試而提供的,在熱重載(hot reload)時會被調(diào)用, 此回調(diào)在Release模式下永遠(yuǎn)不會被調(diào)用
4. Hot Restart 和 Hot Reload 有什么區(qū)別嗎碍讯?
Hot Reload比Hot Restart快悬蔽,Hot Reload會編譯我們文件里新加的代碼并發(fā)送給dart虛擬機(jī),dart會更新widgets來改變UI捉兴,而Hot Restart會讓dart 虛擬機(jī)重新編譯應(yīng)用蝎困。另一方面也是因為這樣, Hot Reload會保留之前的state倍啥,而Hot Restart回你重置所有的state回到初始值禾乘。
5. 在flutter里streams是什么?有幾種streams虽缕?有什么場景用到它始藕?
Stream 用來處理連續(xù)的異步操作,Stream 是一個抽象類,用于表示一序列異步數(shù)據(jù)的源伍派。它是一種產(chǎn)生連續(xù)事件的方式江耀,可以生成數(shù)據(jù)事件或者錯誤事件,以及流結(jié)束時的完成事件
Stream 分單訂閱流和廣播流诉植。
網(wǎng)絡(luò)狀態(tài)的監(jiān)控
6. 簡單說一下在flutter里async和await祥国?
await的出現(xiàn)會把a(bǔ)wait之前和之后的代碼分為兩部分,await并不像字面意思所表示的程序運(yùn)行到這里就阻塞了晾腔,而是立刻結(jié)束當(dāng)前函數(shù)的執(zhí)行并返回一個Future舌稀,函數(shù)內(nèi)剩余代碼通過調(diào)度異步執(zhí)行。
async是和await搭配使用的灼擂,await只在async函數(shù)中出現(xiàn)壁查。在async 函數(shù)里可以沒有await或者有多個await。
7. future 和steam有什么不一樣?
Dart異步編程的兩個特性
Future
和Stream
在 Flutter 中有兩種處理異步操作的方式 Future 和 Stream缤至,F(xiàn)uture 用于處理單個異步操作潮罪,Stream 用來處理連續(xù)的異步操作.
-
Stream
a、Stream 就是事件流或者管道,是一些的異步
事件,它會在上一個事件完成時通知你進(jìn)行下一個事件.
b领斥、Stream無論用什么方式創(chuàng)建,都會以相同的方式返回并使用: asynchronous for loop(await for)
. 例子??:
Future<int> sumStream(Stream<int> stream) async {
var sum = 0;
await for (var value int stream) {
sum += value;
}
return sum;
}
c嫉到、Stream 提供 asynchronous序列化的數(shù)據(jù).
d、該序列化數(shù)據(jù)包含了用戶生成的時間和重文件中讀取的數(shù)據(jù).
e月洛、你可以通過await for 的listen()
來處理Stream API返回的數(shù)據(jù)流.
f何恶、Stream 提供了錯誤相應(yīng)的處理方法.
g、Streams 有兩種方式:single subscription
(訂閱) 和 broadcast
(廣播), 下面是兩種Streams類型說明:
1嚼黔、Single subscription streams (單一訂閱)
- 最常見,最基本的streams實現(xiàn)方式
- 它的數(shù)據(jù)大部分是sequence of events. 單一訂閱必須以正確的順序交付事件,并且中間不能有任何異常
- 這是當(dāng)你在讀取文件或者接受網(wǎng)絡(luò)請求的時候產(chǎn)生的stream.
- 這樣的流不具備冪等性,再次接收可能會不同于上次的請求
- 當(dāng)你開始監(jiān)聽, 數(shù)據(jù)將被提取并以塊的形式提供
2细层、Broadcast streams (廣播)
- 適用于可以一次處理一個的單個消息, 例如:這種流可用于瀏覽器中的鼠標(biāo)事件.
- 可以隨時監(jiān)聽開始監(jiān)聽這樣的流, 并且再收聽時會觸發(fā)事件
- 多個收聽者可以同時收聽, 也可以取消上一個訂閱后再次收聽
-
Future
8. 什么是flutter里的key? 有什么用?
key是Widgets唬涧,Elements和SemanticsNodes的標(biāo)識符疫赎。
key有LocalKey 和 GlobalKey兩種。
LocalKey 如果要修改集合中的控件的順序或數(shù)量碎节。GlobalKey允許 Widget 在應(yīng)用中的任何位置更改父級而不會丟失 State捧搞。
9. 在什么場景下使用profile mode?
profile model 是用來評估app性能的狮荔,profile model 和release mode是相似的胎撇,只有保留了一些需要評估app性能的debug功能。在模擬器上profile model是不可用的殖氏。
10. 怎么做到只在debug mode運(yùn)行代碼晚树?
foundation有一個靜態(tài)的變量kReleaseMode來表示是否是release mode
11. 怎么理解Isolate?
isolate是Dart對actor并發(fā)模式的實現(xiàn)雅采。 isolate是有自己的內(nèi)存和單線程控制的運(yùn)行實體爵憎。isolate本身的意思是“隔離”慨亲,因為isolate之間的內(nèi)存在邏輯上是隔離的。isolate中的代碼是按順序執(zhí)行的纲堵,任何Dart程序的并發(fā)都是運(yùn)行多個isolate的結(jié)果巡雨。因為Dart沒有共享內(nèi)存的并發(fā),沒有競爭的可能性所以不需要鎖席函,也就不用擔(dān)心死鎖的問題
12. 列舉在flutter的狀態(tài)管理方案铐望?
-
Scoped Model
-
Redux
-
BLoC
-
RxDart
-
provider