Flutter基礎(chǔ)知識(shí)

0、Dart是值傳遞還是引用傳遞?

Dart是值傳遞。每次調(diào)用函數(shù),傳遞過去的都是對(duì)象的內(nèi)存地址,不是對(duì)象的復(fù)制。
知識(shí)點(diǎn)擴(kuò)展:Swift的struct是值類型,class是引用類型;意思是:聲明一個(gè)新的變量指向這個(gè)結(jié)構(gòu)體,改變某個(gè)屬性,原本的結(jié)構(gòu)體屬性不會(huì)發(fā)生變化;而類會(huì)隨著改變

1、Flutter的核心樹

Widget:

1、使用配置和狀態(tài),描述view的樣子
2、當(dāng)一個(gè)Widget發(fā)生改變時(shí),Widget會(huì)重新build它的描述

Element:

1、Element是widget的實(shí)例,在樹中詳細(xì)的位置。

RenderObject:

1、渲染樹上的一個(gè)對(duì)象。
2、RenderObject是渲染庫(kù)的核心。

2、flutter 中Widget的分類

1、組合類
statelesswidget、statefullwidget
2、代理類
inheritedwidget:用于狀態(tài)共享,Theme 、Localizations 、 MediaQuery 等,都是通過它進(jìn)行狀態(tài)共享,通過context獲取共享的狀態(tài),ThemeData theme = Theme.of(context);
ParentDataWidget
3、繪制類RenderObjectWidget
RenderObject 的布局相關(guān)方法調(diào)用順序是 : layout -> performResize -> performLayout -> markNeedsPaint

3、mixin extends implement 之間的關(guān)系?

繼承extends 混入mixin 接口實(shí)現(xiàn)implement,三者可以同時(shí)存在,前后順序是extends,mixin,implement。
Flutter的繼承是單繼承,子類重寫超類的方法用override,子類調(diào)用超類的方法用super。
mixin是為了解決繼承方面的問題而引入的機(jī)制,Dart為了支持多重繼承,引入了mixin關(guān)鍵字。mixins的對(duì)象是類,mixins絕不是繼承,也不是接口,而是一種全新的特性,可以mixins多個(gè)類,mixins的使用需要滿足一定條件。
mixin的使用條件:
1、mixin類只能繼承自object
2、mixin類不能有構(gòu)造函數(shù)
3、一個(gè)類可以mixins多個(gè)mixins類,但是不破壞flutter的單繼承
mixin就是為了解決Dart的多繼承問題,但是mixin不能有構(gòu)造方法,避免繼承多個(gè)類產(chǎn)生構(gòu)造方法沖突

4、Dart的語言特性

1、Dart一切都是對(duì)象,所有的對(duì)象繼承自O(shè)bject。
2、Dart和Swift一樣都是強(qiáng)類型語言,可以用var或 dynamic來聲明一個(gè)變量,Dart會(huì)自動(dòng)推斷其數(shù)據(jù)類型。
3、沒有賦值初始值的變量都會(huì)默認(rèn)null
4、Dart支持頂層方法,如main方法,可以在方法內(nèi)部創(chuàng)建方法
5、Dart支持頂層變量,也支持類變量或?qū)ο笞兞?br> 6、Dart沒有public protected private等關(guān)鍵字,如果變量以下劃線開頭(_button),表示這個(gè)變量在庫(kù)中是私有的。

5、Dart 中的級(jí)聯(lián)操作符 (未使用疑問)

Dart 當(dāng)中的 「..」意思是 「級(jí)聯(lián)操作符」,為了方便配置而使用?!?.」和「.」不同的是 調(diào)用「..」后返回的相當(dāng)于是 this,而「.」返回的則是該方法返回的值 。

6、Dart 的單線程模型是如何運(yùn)行的?

Dart在單線程中是以消息循環(huán)機(jī)制來運(yùn)行的,包含兩個(gè)任務(wù)隊(duì)列,微任務(wù)隊(duì)列(microtask queue)、事件隊(duì)列(event queue)。
flutter啟動(dòng)后,消息循環(huán)就啟動(dòng)了。按照先進(jìn)先出原則逐個(gè)執(zhí)行微任務(wù)隊(duì)列中的任務(wù),執(zhí)行完畢后執(zhí)行事件隊(duì)列中的任務(wù),事件隊(duì)列中的任務(wù)執(zhí)行完畢之后,在執(zhí)行微任務(wù)隊(duì)列,如此循環(huán)往復(fù)。

7、await for 與 stream流 (待深入研究)

Stream<String> stream = new Stream<String>.fromIterable(['1', '2', '3', '4']);
main() async{
 print('start');
 await for(String s in stream){
   print(s);
 }
 print('end..');
}
結(jié)果
start
1
2
3
4
end..

await for是不斷獲取stream流中的數(shù)據(jù),然后執(zhí)行循環(huán)體中的操作。await for一般用在知道Stream什么時(shí)候完成,并且必須等待傳遞完成后才能使用,不然就會(huì)一直阻塞。

8、Stream 與 Future的關(guān)系?

1、Future表示稍后獲得的一個(gè)數(shù)據(jù),所有異步操作的返回值都用Future來表示。
2、Future只能表示一次異步獲取的數(shù)據(jù)。
3、Stream表示多次異步獲取的數(shù)據(jù)。例如按鈕多次點(diǎn)擊,這個(gè)點(diǎn)擊事件就是Stream。
4、Future只返回一 次值,Stream返回多次值。
5、Dart中統(tǒng)一使用Stream流處理數(shù)據(jù)。

9、Stream 有哪兩種訂閱模式?分別是怎么調(diào)用的?

Stream單訂閱多訂閱兩種。
Stream 默認(rèn)處于單訂閱模式,所以同一個(gè) stream 上的 listen 和其它大多數(shù)方法只能調(diào)用一次,調(diào)用第二次就會(huì)報(bào)錯(cuò)。
Stream 可以通過 transform() 方法(返回另一個(gè) Stream)進(jìn)行連續(xù)調(diào)用。通過 Stream.asBroadcastStream() 可以將一個(gè)單訂閱模式的 Stream 轉(zhuǎn)換成一個(gè)多訂閱模式的 Stream,isBroadcast 屬性可以判斷當(dāng)前 Stream 所處的模式。

10、Flutter中的Widget、State、Context 的核心概念?是為了解決什么問題?

主要是為了解決多個(gè)部件之間的交互和部件自身狀態(tài)的維護(hù)。
1、Widget: 在Flutter中,幾乎所有東西都是Widget。將一個(gè)Widget想象為一個(gè)可視化的組件(或與應(yīng)用可視化方面交互的組件),當(dāng)你需要構(gòu)建與布局直接或間接相關(guān)的任何內(nèi)容時(shí),你正在使用Widget。
2、Widget樹: Widget以樹結(jié)構(gòu)進(jìn)行組織。包含其他Widget的widget被稱為父Widget(或widget容器)。包含在父widget中的widget被稱為子Widget。
3、Context: 僅僅是已創(chuàng)建的所有Widget樹結(jié)構(gòu)中的某個(gè)Widget的位置引用。簡(jiǎn)而言之,將context作為widget樹的一部分,其中context所對(duì)應(yīng)的widget被添加到此樹中。一個(gè)context只從屬于一個(gè)widget,它和widget一樣是鏈接在一起的,并且會(huì)形成一個(gè)context樹。
4、State: 定義了StatefulWidget實(shí)例的行為,它包含了用于”交互/干預(yù)“Widget信息的行為和布局。應(yīng)用于State的任何更改都會(huì)強(qiáng)制重建Widget。

11、Dart異步編程中的 Future關(guān)鍵字

Dart中,執(zhí)行一個(gè)異步任務(wù)使用Future來處理。
在 Dart 的每一個(gè) Isolate 當(dāng)中,執(zhí)行的優(yōu)先級(jí)為 :Main > MicroTask > EventQueue。

12、什么是Isolate?

Dart只有一個(gè)主線程,其實(shí)在Dart中并不是叫 Thread ,而是有個(gè)專門名詞叫 「isolate(隔離)。
用官方文檔中定義一句話來概括: An isolated Dart execution context .大概的意思就是「isolate實(shí)際就是一個(gè)隔離的Dart執(zhí)行的上下文環(huán)境(或者容器)」?!竔solate是有自己的內(nèi)存和單線程控制的事件循環(huán)」

其實(shí)在Dart也會(huì)遇到一些耗時(shí)計(jì)算的任務(wù),不建議把任務(wù)放在主isolate中,否則容易造成UI卡頓,需要開辟一個(gè)單獨(dú)isolate來獨(dú)立執(zhí)行耗時(shí)任務(wù),然后通過消息機(jī)制把最終計(jì)算結(jié)果發(fā)送給主isolate實(shí)現(xiàn)UI的更新。」 在Dart中異步是并發(fā)方案的基礎(chǔ),Dart支持單個(gè)和多個(gè)isolate中的異步。。
「Dart沒有共享內(nèi)存的并發(fā)」,沒有競(jìng)爭(zhēng)的可能性所以不需要鎖,也就不存在死鎖的問題。
Flutter異步編程-Isolate

13、Flutter 中的生命周期

13.1 statefulWidget
1、initState→didChangeDependence→build→didupdateDependence→deactivate→dispose

2、initState:只調(diào)用一次,widget創(chuàng)建執(zhí)行的第一個(gè)方法,這里可以做初始化工作,不如初始化state變量。
3、didChangeDependence:多次調(diào)用。
1、initState調(diào)用
2、依賴的InheritedWidget rebuild會(huì)被調(diào)用。
3、build:多次調(diào)用
1、initState調(diào)用
2、setState觸發(fā)的時(shí)候調(diào)用
4、didupdateDependence:多次調(diào)用
組件狀態(tài)改變的時(shí)候調(diào)用
5、deactivate:調(diào)用一次
當(dāng)State對(duì)象從樹中被移除,會(huì)調(diào)用此回調(diào),會(huì)在dispose之前調(diào)用。
頁(yè)面銷毀的時(shí)候會(huì)依次執(zhí)行:deactivate → dispose
6、dispose:調(diào)用一次
當(dāng)State對(duì)象從樹中被永久移除時(shí)調(diào)用;通常在此方法中釋放資源。

13.2 statelessWidget

1、builde
2、update

14、flutter和RN

flutter與RN的相同點(diǎn):
1.都是移動(dòng)開發(fā)跨臺(tái)解決方案
2.界面的編寫都采用響應(yīng)式視圖,維護(hù)了一個(gè)狀態(tài)機(jī),只更新改變的最小區(qū)域界面
3.都支持熱重載hot reload,開發(fā)調(diào)試非常方便
4.調(diào)用系統(tǒng)的service仍然需要封裝接口,仍然還是需要懂得native開發(fā)
flutter與RN 的區(qū)別:

  1. 性能方面:
    Flutter由于是基于Dart語言, 所以避免了RN的那種通過橋接器與Javascript通訊導(dǎo)致效率低下的問題,所以在性能方面比RN更高一籌,會(huì)更接近原生的體驗(yàn).
  2. 學(xué)習(xí)成本方面:
    Flutter是基于Dart語言,相對(duì)來說,由于要學(xué)習(xí)一門新的開發(fā)語言所以學(xué)習(xí)成本比較高, 而RN采用JS語言開發(fā),基于React,對(duì)前端工程師更友好.
  3. UI 樣式方面:
    flutter實(shí)現(xiàn)跨平臺(tái)采用了更為徹底的方案, 因?yàn)樗赾anvas自己實(shí)現(xiàn)了一套UI框架, 所以兼容性更好, 而 RN 在在樣式方面還是會(huì)遇到比較多的問題,且解決起來會(huì)有點(diǎn)麻煩.
    4.成熟度的方面:
    React Native 是在 2015 年發(fā)布的,經(jīng)過 3 年多的發(fā)展,已經(jīng)比較成熟, 雖然也還不完善, 但是Flutter 是在今年 6 月份才推出發(fā)布預(yù)覽版,社區(qū)也剛剛發(fā)展, 在github上還有兩千多個(gè)待解決的問題,所以flutter需要更多時(shí)間。

flutter的有一套自己的UI框架,所以兼容性更好,且由于RN需要橋接器和JavaScript通訊,導(dǎo)致效率低下,flutter更接近原生體驗(yàn)。

15、Flutter 線程管理模型 (待加強(qiáng))

Flutter Engine層會(huì)創(chuàng)建一個(gè)Isolate,并且Dart代碼默認(rèn)就運(yùn)行在這個(gè)主Isolate上。必要時(shí)可以使用spawnUri和spawn兩種方式來創(chuàng)建新的Isolate,在Flutter中,新創(chuàng)建的Isolate由Flutter進(jìn)行統(tǒng)一的管理。
事實(shí)上,F(xiàn)lutter Engine自己不創(chuàng)建和管理線程,F(xiàn)lutter Engine線程的創(chuàng)建和管理是Embeder負(fù)責(zé)的,Embeder指的是將引擎移植到平臺(tái)的中間層代碼。
Flutter 中存在的四大線程:分別為 UI Runner、GPU Runner、IO Runner, Platform Runner (原生主線程) ,在 Flutter 中可以通過 isolate 或者 compute 執(zhí)行真正的跨線程異步操作。

16、Flutter狀態(tài)管理

Flutter的狀態(tài)可以分為全局狀態(tài)和局部狀態(tài)兩種。
常用的狀態(tài)管理都是基于InheritedWidget封裝的用于Widget樹的數(shù)據(jù)傳遞與共享的的一套框架。
Provider是繼承于InheritProvider,而InheritProvider本質(zhì)上是一個(gè)InheritWidget,所以Provider本質(zhì)上是依托于InheritProvider的機(jī)制來實(shí)現(xiàn)的widget樹的狀態(tài)共享。
總結(jié):Provider本質(zhì)上是依托于InheritProvider的機(jī)制來來實(shí)現(xiàn)widget樹的共享。

17、isolate是怎么進(jìn)行通信和實(shí)例化的?

1、isolate是一個(gè)隔離Dart執(zhí)行的上下文環(huán)境。
2、isolate有自己的內(nèi)容和單線程控制的事件循環(huán)。
3、isolate之間的內(nèi)存邏輯上是隔離的,不共享內(nèi)存。
4、任何Dart程序的并發(fā)都是運(yùn)行多個(gè)isolate的結(jié)果。Dart沒有共享內(nèi)存的并發(fā),所以不存在死鎖問題。
isolate線程之間的通信主要通過port來進(jìn)行,這個(gè)port消息傳遞過程是異步的。

18、Future還是isolate場(chǎng)景分析?

1、如果一段代碼不會(huì)被中斷,那么就直接使用正常的同步執(zhí)行就行。
2、如果代碼段可以獨(dú)立運(yùn)行而不會(huì)影響應(yīng)用程序的流暢性,建議使用 Future (需要花費(fèi)幾毫秒時(shí)間)
3、如果繁重的處理可能要花一些時(shí)間才能完成,而且會(huì)影響應(yīng)用程序的流暢性,建議使用 isolate (需要幾百毫秒)
使用 isolate 的具體場(chǎng)景:
1、JSON解析: 解碼JSON,這是HttpRequest的結(jié)果,可能需要一些時(shí)間,可以使用封裝好的 isolate 的 compute 頂層方法。
2、加解密: 加解密過程比較耗時(shí)
3、圖片處理: 比如裁剪圖片比較耗時(shí)
4、從網(wǎng)絡(luò)中加載大圖

19、Flutter 是如何與原生Android、iOS進(jìn)行通信的?(重點(diǎn)了解)

Flutter 通過 PlatformChannel 與原生進(jìn)行交互,其中 PlatformChannel 分為三種:
BasicMessageChannel :用于傳遞字符串和半結(jié)構(gòu)化的信息。
MethodChannel :用于傳遞方法調(diào)用(method invocation)。
EventChannel : 用于數(shù)據(jù)流(event streams)的通信。

20、Flutter 繪制流程

GPU的VSync信號(hào)同步到UI線程,UI線程使用Dart來構(gòu)建抽象視圖結(jié)構(gòu)。然后,這些數(shù)據(jù)結(jié)構(gòu)在GPU中進(jìn)行圖層合成,視圖數(shù)據(jù)提供給 Skia引擎渲染為 GPU數(shù)據(jù),這些數(shù)據(jù)通過 OpenGL或者 Vulkan提供給 GPU。

21、PlatformView

platform view 就是 AndroidView 和 UIKitView 的總稱,允許將 native view 嵌入到了 flutter widget 體系中,完成 Dart 代碼對(duì) native view 的控制。
鏈接:http://www.itdecent.cn/p/9306d7ecde35

22、Flutter的理念架構(gòu)

image.png

1、Framework層則是使用Dart編寫的一套基礎(chǔ)視圖庫(kù),包含了動(dòng)畫、圖形繪制和手勢(shì)識(shí)別等功能,是使用頻率最高的一層。
2、Engine層負(fù)責(zé)圖形繪制、文字排版和提供Dart運(yùn)行時(shí),Engine層具有獨(dú)立虛擬機(jī),正是由于它的存在,F(xiàn)lutter程序才能運(yùn)行在不同的平臺(tái)上。
3、Embedder是操作系統(tǒng)適配層,實(shí)現(xiàn)了渲染。

參考:http://www.itdecent.cn/p/9064a68a05ae

23、flutter的key和context

1、key:是flutter用來標(biāo)記widget的唯一標(biāo)識(shí)。
  • Local Key(局部key):分為Value Key、Object Key和Unique Key,必須要有唯一性。
    Local Key顧名思義,指的是在當(dāng)前Widget層級(jí)下,有唯一的Key屬性??梢杂胕nt或者string來表示。
1.1 Value Key使用事例如下

使用學(xué)生的學(xué)號(hào)或者身份證號(hào)等唯一的標(biāo)識(shí)來標(biāo)識(shí)。


Value Key
1.2 Object Key

通過對(duì)比對(duì)象的地址來判斷是否相同,下同new了兩次Student,所以key是不同的,如果使用同一個(gè)對(duì)象就會(huì)報(bào)錯(cuò)。


Object Key
1.3 Unique Key

實(shí)在找不到什么標(biāo)識(shí)的話我們可以使用UniqueKey來進(jìn)行標(biāo)記,自動(dòng)生成唯一的key。


Unique Key
  • Global Key (全局key):在全局APP中,具有唯一性。Global Key的性能會(huì)比Local Key差很多。
    Global Key使用場(chǎng)景,一是讓widget在Widget Tree發(fā)生大幅改動(dòng)的時(shí)候仍然保留狀態(tài),二是像JavaScript里面getElementById那樣查找某個(gè)元素并得到它的各種信息。
final  _globalKey1 =  GlobalKey ();
final  _globalKey2 =  GlobalKey ();
橫豎屏保持狀態(tài)

獲取全局的數(shù)據(jù)信息:



image.png
2、context:是指widget在Widget樹中的具體位置,flutter就是根據(jù)context包含的信息,來繪制widget及其對(duì)應(yīng)的位置。

24、Flutter 空安全

空安全(Sound null safety)是Flutter 更新之后 Dart 中新增的一項(xiàng)特性,swift語言也有此特性。有了空安全,Dart 分析器可以進(jìn)行更好的檢查。與空安全相關(guān)的新操作符和關(guān)鍵字有 ?、!。
在空安全之前,是可以直接賦值為null,且可以通過編譯,這個(gè)就說空安全與之前最大的不同,而且是在編譯階段就直接報(bào)異常錯(cuò)誤。
在使用空安全的情況下,我們想讓變量賦值為null時(shí),我們可以這樣處理:

 int? count = null;
 String? name = null;
只需在類型后面添加 ? 即可
類型后面跟操作符 ? 表示當(dāng)前變量可為null。

總結(jié):
操作符 ? :放在類型后面表示當(dāng)前變量可為null,例如 String a 和 String ? b ,a 不能為null,而 b 可以。
操作符 !:表示此變量值不為null,如果為null則會(huì)拋出異常。使用請(qǐng)慎重考慮。

25、flutter和原生交互傳參的方式

Flutter和Xcode混編
重點(diǎn)總結(jié):

1、flutter調(diào)用OC傳參,需要使用MethodChannel

1、flutter內(nèi)部點(diǎn)擊事件傳參

//  用于調(diào)用原生方法  "hometestmethod"標(biāo)識(shí)符與OC中的監(jiān)聽標(biāo)識(shí)符保持一致
  var homechannelmethod = MethodChannel("hometestmethod");
// 點(diǎn)擊
  onTap: (){
        //給原生發(fā)送消息并傳入?yún)?shù),原生根據(jù)標(biāo)識(shí)homePageCallNativeMethond來做對(duì)應(yīng)的處理
        homechannelmethod.invokeMethod('homePageCallNativeMethond',{"key":"value","key1":"value1"});
      },

2、OC接受傳參

//    1.創(chuàng)建方法通道對(duì)象,用于監(jiān)聽flutter調(diào)用原生時(shí)的回調(diào),唯一標(biāo)識(shí)“hometestmethod”與flutter要保持一致
    FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"hometestmethod" binaryMessenger:flutterViewController.binaryMessenger];
    //2. 設(shè)置監(jiān)聽回調(diào)block,flutter端通過通道調(diào)用原生方法時(shí)會(huì)進(jìn)入以下回調(diào)
    [channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        //call的屬性method是flutter調(diào)用原生方法的方法名,我們進(jìn)行字符串判斷然后寫入不同的邏輯
        if ([call.method isEqualToString:@"homePageCallNativeMethond"]) {
            //flutter傳給原生的參數(shù)
            id para = call.arguments;
            NSLog(@"flutter傳給原生的參數(shù):%@", para);
            //可以做界面跳轉(zhuǎn)
            [self.navigationController pushViewController:[TestViewController new] animated:YES];
            //獲取一個(gè)字符串
            NSString *nativeFinalStr = @"原生給flutter回傳的值";
            if (nativeFinalStr!=nil) {
                //把獲取到的字符串傳值給flutter
                result(nativeFinalStr);
            }else{
                //異常(比如改方法是調(diào)用原生的getString獲取一個(gè)字符串,但是返回的是nil(空值),這顯然是不對(duì)的,就可以向flutter拋出異常 進(jìn)入catch處理)
                result([FlutterError errorWithCode:@"001" message:[NSString stringWithFormat:@"進(jìn)入異常處理"] details:@"進(jìn)入flutter的trycatch方法的catch方法"]);
            }
        }else{
            //調(diào)用的方法原生沒有對(duì)應(yīng)的處理  拋出未實(shí)現(xiàn)的異常
            result(FlutterMethodNotImplemented);
        }
    }];
2、OC調(diào)用FLuttter傳參,需要調(diào)用EventChannel,通過代理傳參。
//1. 創(chuàng)建事件通道對(duì)象,唯一標(biāo)識(shí) “hometest”,到時(shí)flutter是根據(jù)該標(biāo)識(shí)來監(jiān)聽原生發(fā)送給flutter的參數(shù)信息
    FlutterEventChannel *evenChannel = [FlutterEventChannel eventChannelWithName:@"hometest" binaryMessenger:flutterViewController.binaryMessenger];
    //2. 當(dāng)原生跳往flutter時(shí)會(huì)觸發(fā)下面的- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events回調(diào)方法,可以在該方法中給flutter傳遞參數(shù)
    [evenChannel setStreamHandler:self];

//原生跳轉(zhuǎn)flutter時(shí),會(huì)觸發(fā)該方法,在該方法中可以傳遞參數(shù)給flutter界面,需要注意的是flutter代碼中必須寫上對(duì)應(yīng)的監(jiān)聽代碼,這里才會(huì)被執(zhí)行
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events{
    if (events) {
        events(@{@"key":@"value"});
    }
    return nil;
}

26、本地?cái)?shù)據(jù)存儲(chǔ)方式

文件、sharedPreferences、sqlite數(shù)據(jù)庫(kù)

和原生通訊方式

Flutter定義了三種不同類型的channel,分別是

eventChannel:用于數(shù)據(jù)流通信,原生向Flutter傳參,通過代理eventSink傳參。

methodChannelflutter向原生傳參。定義好方法名

BaseMessageChannel:未使用

27、鍵盤高度超出解決

Scaffold(

resizeToAvoidBottomPadding: false, //輸入框抵住鍵盤

)

28、ListView報(bào)Vertical viewport was given unbounded height錯(cuò)誤解決方法

原因:寬高溢出。導(dǎo)致widget不顯示

解決:給ListView的shrinkWrap屬性設(shè)置為ture(收縮)。父視圖的大小跟隨子組件內(nèi)容大小。

29、Flutter報(bào)setState() or markNeedsBuild() called during build.錯(cuò)誤解決辦法

錯(cuò)誤原因:在運(yùn)行中,控件和響應(yīng)事件沒有構(gòu)建完,延時(shí)加載就可解決問題

解決方法:使用Future延時(shí)

void _addIndex() {
 Future.delayed(Duration(milliseconds: 200)).then((e) {
  setState(() {});
});
}
}

30、Flutter報(bào)setState() called after dispose()錯(cuò)誤解決辦法

錯(cuò)誤解析:防止頁(yè)面關(guān)閉執(zhí)行setState()方法
解決方法:mountedmounted 表明 State 當(dāng)前是否正確綁定在View樹中。State的生命周期里面,這個(gè) mounted 屬性不會(huì)改變,直至 framework 調(diào)用 State.dispose,當(dāng)改變之后, State 對(duì)象再也不會(huì)調(diào)用 build 方法 mounted = false。

31、實(shí)現(xiàn)水波紋

InkWell

32、安卓和iOS 控件區(qū)別

Flutter提供了兩種不同風(fēng)格安卓的MaterialiOSCupertino風(fēng)格

33、StatelessWidget的生命周期有哪些,請(qǐng)按生命周期順序說一下?

只有build,update。

34、Flutter是怎么實(shí)現(xiàn)熱重載的,說說具體實(shí)現(xiàn)原理?

Flutter的 Debug 模式支持 JIT(Just In Time),指的是即時(shí)編譯或運(yùn)行時(shí)編譯,

JIT 編譯器將 Dart 代碼編譯成可以運(yùn)行在 Dart VM 上的 Dart Kernel, Dart Kernel可以動(dòng)態(tài)更新。

35、為什么說Flutter的性能好,與RN的區(qū)別?

1、flutter沒有橋接層。

2、自帶渲染引擎。skia

3、編譯執(zhí)行。JS是解釋執(zhí)行。

4、Flutter Engine虛擬機(jī)

36、Flutter中是怎么實(shí)現(xiàn)并發(fā)操作的?

兩種方式:isolate 和 Future

Future:短時(shí)間的幾毫秒。

isolate:長(zhǎng)時(shí)間幾百毫秒

37、isolate是怎么進(jìn)行通信和實(shí)例化的?

通信:通過port實(shí)現(xiàn)通信,sendPort和reservePort,這個(gè)port消息傳遞過程是異步的。

實(shí)例化: Isolate isolate =await Isolate.spawn<SendPort>(dataLoader, mainThreadPort.sendPort);

重點(diǎn),深刻解析: https://www.bbsmax.com/A/kjdwe1NBJN/

38、Future和isolate有什么區(qū)別?

Future: 是一個(gè)異步執(zhí)行并且在未來的某一個(gè)時(shí)刻完成(或失?。┑娜蝿?wù)。Future本質(zhì)上 并非并行執(zhí)行,而是遵循事件循環(huán)處理事件的順序規(guī)則執(zhí)行。

isolate:為了并行運(yùn)行代碼。每個(gè)isolate都有自己的事件循環(huán)。

總結(jié):

  • 如果一個(gè)方法需要幾毫秒使用Future
  • 如果一個(gè)處理流程需要幾百毫秒使用isolate

使用isolate場(chǎng)景:

  • JSON解碼
  • 加密
  • 圖像處理:裁剪
  • 從web加載圖像

39、Stream與Future是什么關(guān)系?

Future:只能接收一次返回的數(shù)據(jù)

Stream:接收多次返回的數(shù)據(jù)。flutter就是基于Stream流的處理。

40、setState是同步還是異步操作

setState是異步操作。下面代碼的打印先輸出2然后在輸出1.

onChanged:(value) async{
    setState(){
        print('1111111')  ;
  }
        print('222222')  ;
}

41、setState無效

Flutter開發(fā)App時(shí),偶爾會(huì)遇到SetState()不起作用或界面更新不完全的Bug,是什么原因?qū)е碌哪兀?br> 比如在彈窗中點(diǎn)擊,標(biāo)記對(duì)號(hào)。我們是使用系統(tǒng)的彈窗SimpleDialog來展示,但是點(diǎn)擊之后標(biāo)記框狀態(tài)沒有改變,這是為什么呢?因?yàn)镾impleDialog是無狀態(tài)組件,要解決問題,我們需要包裹StateFulBuilder 如下:


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容