1、Dart是什么? 和Flutter是什么關(guān)系?
Dart是Google開發(fā)的一種面向?qū)ο蟮挠?jì)算機(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)常需要繼承它們兩來實(shí)現(xiàn)自己的 Widget。
A、無狀態(tài)的StatelessWidget
如果你的控件一旦顯示,就不需要再做任何的變更,那么你應(yīng)該使用 StatelessWidget。
實(shí)現(xiàn)一個(gè)自己的 StatelessWidget 很簡單。
當(dāng)你看到下面這個(gè)例子??時(shí),你就知道它有多簡單了。
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)是因?yàn)?code>setState,當(dāng)調(diào)用setState后,就會觸發(fā) StatefulWidget 的視圖樹重建。
setState((){
// 更新狀態(tài)、數(shù)據(jù)
})
因此,當(dāng)我們需要一個(gè)可交互的,即能根據(jù)用戶操作或數(shù)據(jù)變化而改變視圖的 Widget 時(shí),那就得用上 StatefulWidget 了。
周期
State的生命周期和StatefulWidget不同,當(dāng)StatefulWidget的狀態(tài)改變之后就會被重建,但是State不會改變,但是 StatefulWidget在View樹中移除再插入又會生成新的State.

總體介紹一下生命周期,大致可以看成三個(gè)階段:
- 初始化 (插入渲染樹??)
- 狀態(tài)改變 (在渲染樹中存在)
- 銷毀 (從渲染樹中移除)
生命周期詳解
initState
當(dāng)插入渲染樹的時(shí)候調(diào)用,這個(gè)函數(shù)在生命周期中只調(diào)用一次. 這里可以做一些初始化的工作,比如初始化State的變量
didChangeDependencies
這個(gè)函數(shù)會緊跟在initState之后調(diào)用,并且可以調(diào)用BuildContext.inheritFromWidgetOfExactType, 那么BuildContext.inheritFromWidgetOfExactType的使用場景是什么呢?
static TabController of(BuildContext context) {
final _TabControllerScope scope = context.inheritFromWidgetOfExactType(_TabControllerScope);
return scope?.controller;
}
實(shí)際上就是調(diào)用BuildContext.inheritFromWidgetOfExactType,也就是說在didChangeDependencies中,可以跨組件拿到數(shù)據(jù)
didUpdateWidget
當(dāng)組件的狀態(tài)改變的時(shí)候就會調(diào)用didUpdateWidget, 比如調(diào)用setState,
實(shí)際flutter框架會創(chuàng)建一個(gè)新的Widget綁定State,并在函數(shù)中傳遞老的Widget.
這個(gè)函數(shù)一般用于比較新、老Widget,看看哪些屬性改變了,并對State做一些調(diào)整.
需要注意的是涉及到controller的變更,需要在這個(gè)函數(shù)中移除老的controller的監(jiān)聽,并創(chuàng)建新controller.
deactivate
在dispoes之前,會調(diào)用這個(gè)函數(shù)
dispose
一旦到這個(gè)階段,組件就會被銷毀,這個(gè)函數(shù)一般會移除監(jiān)聽,清理環(huán)境
總結(jié)
| 階段 | 調(diào)用次數(shù) |
|---|---|
| 構(gòu)造函數(shù) | 1 |
| initState | 1 |
| didChangeDependencies | >=1 |
| didUpdateWidget | >=1 |
| deactivate | >=1 |
| dispose | 1 |
各方解釋
- initState: 插入渲染樹時(shí)調(diào)用只調(diào)用一次, widget創(chuàng)建執(zhí)行的第一個(gè)方法, 可以再里面初始化一些數(shù)據(jù),以及綁定控制器
- didChangeDependencies: 當(dāng)State對象的依賴發(fā)生變化時(shí)被調(diào)用
- build: 它主要用戶構(gòu)建Widget字樹的,調(diào)用次數(shù):多次,初始化之后開始繪制界面,當(dāng)調(diào)用setState觸發(fā)的時(shí)候會再次被調(diào)用
- deactivate: 當(dāng)State被暫時(shí)從視圖樹中移除時(shí),會調(diào)用這個(gè)函數(shù).
頁面切換時(shí)也會調(diào)用它,因?yàn)榇藭r(shí)State在視圖樹中的位置發(fā)送了變化,需要先暫時(shí)移除后添加 - dispose: 當(dāng)State對象從樹中被永久移除時(shí)調(diào)用; 通常在此回調(diào)中釋放資源.
- reassemble: 此回調(diào)是為了專門開發(fā)調(diào)試而提供的,在熱重載(hot reload)時(shí)會被調(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)用。另一方面也是因?yàn)檫@樣, Hot Reload會保留之前的state,而Hot Restart回你重置所有的state回到初始值。
5. 在flutter里streams是什么?有幾種streams?有什么場景用到它?
Stream 用來處理連續(xù)的異步操作,Stream 是一個(gè)抽象類,用于表示一序列異步數(shù)據(jù)的源。它是一種產(chǎn)生連續(xù)事件的方式,可以生成數(shù)據(jù)事件或者錯(cuò)誤事件,以及流結(jié)束時(shí)的完成事件
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í)行并返回一個(gè)Future,函數(shù)內(nèi)剩余代碼通過調(diào)度異步執(zhí)行。
async是和await搭配使用的,await只在async函數(shù)中出現(xiàn)。在async 函數(shù)里可以沒有await或者有多個(gè)await。
7. future 和steam有什么不一樣?
Dart異步編程的兩個(gè)特性
Future和Stream
在 Flutter 中有兩種處理異步操作的方式 Future 和 Stream,F(xiàn)uture 用于處理單個(gè)異步操作,Stream 用來處理連續(xù)的異步操作.
-
Stream
a、Stream 就是事件流或者管道,是一些的異步事件,它會在上一個(gè)事件完成時(shí)通知你進(jìn)行下一個(gè)事件.
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í)間和重文件中讀取的數(shù)據(jù).
e、你可以通過await for 的listen()來處理Stream API返回的數(shù)據(jù)流.
f、Stream 提供了錯(cuò)誤相應(yīng)的處理方法.
g、Streams 有兩種方式:single subscription(訂閱) 和 broadcast (廣播), 下面是兩種Streams類型說明:
1、Single subscription streams (單一訂閱)
- 最常見,最基本的streams實(shí)現(xiàn)方式
- 它的數(shù)據(jù)大部分是sequence of events. 單一訂閱必須以正確的順序交付事件,并且中間不能有任何異常
- 這是當(dāng)你在讀取文件或者接受網(wǎng)絡(luò)請求的時(shí)候產(chǎn)生的stream.
- 這樣的流不具備冪等性,再次接收可能會不同于上次的請求
- 當(dāng)你開始監(jiān)聽, 數(shù)據(jù)將被提取并以塊的形式提供
2、Broadcast streams (廣播)
- 適用于可以一次處理一個(gè)的單個(gè)消息, 例如:這種流可用于瀏覽器中的鼠標(biāo)事件.
- 可以隨時(shí)監(jiān)聽開始監(jiān)聽這樣的流, 并且再收聽時(shí)會觸發(fā)事件
- 多個(gè)收聽者可以同時(shí)收聽, 也可以取消上一個(gè)訂閱后再次收聽
-
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有一個(gè)靜態(tài)的變量kReleaseMode來表示是否是release mode
11. 怎么理解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)心死鎖的問題
12. 列舉在flutter的狀態(tài)管理方案?
-
Scoped Model
-
Redux
-
BLoC
-
RxDart
-
provider