? ? ? 人就是孤獨(dú)的约谈,壓力太大笔宿,緩解它帶來(lái)的痛苦的唯一方式就是平靜的接受它犁钟;擺脫痛苦的一種方式也只有努力,讓自己蛻變泼橘。
堅(jiān)持自己的路涝动,要么成為外人眼里的瘋子,要么成為外人眼里的傳奇炬灭。
別人都在t偷偷默默的努力醋粟,只是你自己不知道而已,兩年重归,三年米愿,五年,漸行漸遠(yuǎn).......
? ?以后自己會(huì)寫(xiě)一些開(kāi)源的組件 上傳到 :https://github.com/oywl316644570? ?歡迎? Fork 與 Star? 鼻吮。
對(duì)于Flutter ,經(jīng)過(guò)3個(gè)月斷斷續(xù)續(xù)的學(xué)習(xí),終于成功入門(mén)能夠進(jìn)行初級(jí)開(kāi)發(fā)育苟,也算是初階告一段落,接下來(lái)會(huì)慢慢進(jìn)攻中階學(xué)習(xí)...
今天抽時(shí)間記錄下自己的學(xué)習(xí)心得椎木,及問(wèn)題總結(jié):
1. dart是什么违柏,和flutter有什么關(guān)系?
? ? dart是一種面向?qū)ο笳Z(yǔ)言拓哺,dart是flutter的程序開(kāi)發(fā)語(yǔ)言勇垛。
2. main()和runApp()函數(shù)在flutter的作用分別是什么?有什么關(guān)系嗎士鸥?
? ? main函數(shù)是類(lèi)似于java語(yǔ)言的程序運(yùn)行入口函數(shù)
? ? runApp函數(shù)是渲染根widget樹(shù)的函數(shù)
? ? 一般情況下runApp函數(shù)會(huì)在main函數(shù)里執(zhí)行
3. 什么是widget?? 在flutter里有幾種類(lèi)型的widget闲孤?分別有什么區(qū)別?能分別說(shuō)一下生命周期嗎烤礁?? ? ? ??
????widget在flutter里基本是一些UI組件
????有兩種類(lèi)型的widget讼积,分別是statefulWidget 和 statelessWidget兩種
????statelessWidget不會(huì)自己重新構(gòu)建自己,但是statefulWidget會(huì)????
4. Hot Restart 和 Hot Reload 有什么區(qū)別嗎脚仔?
? ? Hot Reload比Hot Restart快勤众,Hot Reload會(huì)編譯我們文件里新加的代碼并發(fā)送給dart虛擬機(jī),dart會(huì)更新widgets來(lái)改變UI鲤脏,而Hot Restart會(huì)讓dart 虛擬機(jī)重新編譯應(yīng)用们颜。另一方面也是因?yàn)檫@樣,?Hot Reload會(huì)保留之前的state猎醇,而Hot Restart回你重置所有的state回到初始值窥突。
5.? 簡(jiǎn)單說(shuō)一下在flutter里async和await?
? ? await的出現(xiàn)會(huì)把a(bǔ)wait之前和之后的代碼分為兩部分硫嘶,await并不像字面意思所表示的程序運(yùn)行到這里就阻塞了阻问,而是立刻結(jié)束當(dāng)前函數(shù)的執(zhí)行并返回一個(gè)Future,函數(shù)內(nèi)剩余代碼通過(guò)調(diào)度異步執(zhí)行沦疾。
? ? async是和await搭配使用的称近,await只在async函數(shù)中出現(xiàn)第队。在async 函數(shù)里可以沒(méi)有await或者有多個(gè)await。
6. future 和steam有什么不一樣刨秆??
????在 Flutter 中有兩種處理異步操作的方式?Future?和?Stream凳谦,F(xiàn)uture?用于處理單個(gè)異步操作,Stream?用來(lái)處理連續(xù)的異步操作坛善。
7. 怎么理解Isolate晾蜘?? ?
? ???isolate是Dart對(duì)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沒(méi)有共享內(nèi)存的并發(fā),沒(méi)有競(jìng)爭(zhēng)的可能性所以不需要鎖葫督,也就不用擔(dān)心死鎖的問(wèn)題
Dart
1. Dart 當(dāng)中的 「..」表示什么意思竭鞍?
Dart 當(dāng)中的 「..」意思是 「級(jí)聯(lián)操作符」,為了方便配置而使用橄镜≠丝欤「..」和「.」不同的是 調(diào)用「..」后返回的相當(dāng)于是 this,而「.」返回的則是該方法返回的值 洽胶。
2. Dart 的作用域
Dart 沒(méi)有 「public」「private」等關(guān)鍵字晒夹,默認(rèn)就是公開(kāi)的,私有變量使用 下劃線 _開(kāi)頭姊氓。
3. Dart 是不是單線程模型丐怯?是如何運(yùn)行的?
Dart 是單線程模型翔横,
簡(jiǎn)單來(lái)說(shuō)读跷,Dart 在單線程中是以消息循環(huán)機(jī)制來(lái)運(yùn)行的,包含兩個(gè)任務(wù)隊(duì)列禾唁,一個(gè)是“微任務(wù)隊(duì)列” microtask queue效览,另一個(gè)叫做“事件隊(duì)列” event queue。
當(dāng)Flutter應(yīng)用啟動(dòng)后荡短,消息循環(huán)機(jī)制便啟動(dòng)了丐枉。首先會(huì)按照先進(jìn)先出的順序逐個(gè)執(zhí)行微任務(wù)隊(duì)列中的任務(wù),當(dāng)所有微任務(wù)隊(duì)列執(zhí)行完后便開(kāi)始執(zhí)行事件隊(duì)列中的任務(wù)肢预,事件任務(wù)執(zhí)行完畢后再去執(zhí)行微任務(wù)矛洞,如此循環(huán)往復(fù)洼哎,生生不息烫映。
4. Dart 是如何實(shí)現(xiàn)多任務(wù)并行的沼本?
前面說(shuō)過(guò), Dart 是單線程的锭沟,不存在多線程抽兆,那如何進(jìn)行多任務(wù)并行的呢?其實(shí)族淮,Dart的多線程和前端的多線程有很多的相似之處辫红。Flutter的多線程主要依賴(lài)Dart的并發(fā)編程、異步和事件驅(qū)動(dòng)機(jī)制祝辣。
簡(jiǎn)單的說(shuō)贴妻,在Dart中,一個(gè)Isolate對(duì)象其實(shí)就是一個(gè)isolate執(zhí)行環(huán)境的引用蝙斜,一般來(lái)說(shuō)我們都是通過(guò)當(dāng)前的isolate去控制其他的isolate完成彼此之間的交互名惩,而當(dāng)我們想要?jiǎng)?chuàng)建一個(gè)新的Isolate可以使用Isolate.spawn方法獲取返回的一個(gè)新的isolate對(duì)象,兩個(gè)isolate之間使用SendPort相互發(fā)送消息孕荠,而isolate中也存在了一個(gè)與之對(duì)應(yīng)的ReceivePort接受消息用來(lái)處理娩鹉,但是我們需要注意的是,ReceivePort和SendPort在每個(gè)isolate都有一對(duì)稚伍,只有同一個(gè)isolate中的ReceivePort才能接受到當(dāng)前類(lèi)的SendPort發(fā)送的消息并且處理弯予。
5. 說(shuō)一下Dart異步編程中的 Future關(guān)鍵字?
前面說(shuō)過(guò)个曙,Dart 在單線程中是以消息循環(huán)機(jī)制來(lái)運(yùn)行的锈嫩,其中包含兩個(gè)任務(wù)隊(duì)列,一個(gè)是“微任務(wù)隊(duì)列” microtask queue困檩,另一個(gè)叫做“事件隊(duì)列” event queue祠挫。
在Java并發(fā)編程開(kāi)發(fā)中,經(jīng)常會(huì)使用Future來(lái)處理異步或者延遲處理任務(wù)等操作悼沿。而在Dart中等舔,執(zhí)行一個(gè)異步任務(wù)同樣也可以使用Future來(lái)處理。在
Dart 的每一個(gè) Isolate 當(dāng)中糟趾,執(zhí)行的優(yōu)先級(jí)為 :Main > MicroTask > EventQueue慌植。
6. 說(shuō)一下Dart異步編程中的 Stream數(shù)據(jù)流?
在Dart中义郑,Stream 和 Future 一樣蝶柿,都是用來(lái)處理異步編程的工具外里。它們的區(qū)別在于推汽,Stream 可以接收多個(gè)異步結(jié)果社露,而Future 只有一個(gè)等孵。
Stream 的創(chuàng)建可以使用 Stream.fromFuture灌侣,也可以使用 StreamController 來(lái)創(chuàng)建和控制。還有一個(gè)注意點(diǎn)是:普通的 Stream 只可以有一個(gè)訂閱者负乡,如果想要多訂閱的話胚宦,要使用 asBroadcastStream()。
7. Stream 有哪兩種訂閱模式戒洼?分別是怎么調(diào)用的俏橘?
Stream有兩種訂閱模式:?jiǎn)斡嗛?single) 和 多訂閱(broadcast)。單訂閱就是只能有一個(gè)訂閱者圈浇,而廣播是可以有多個(gè)訂閱者寥掐。這就有點(diǎn)類(lèi)似于消息服務(wù)(Message Service)的處理模式。單訂閱類(lèi)似于點(diǎn)對(duì)點(diǎn)磷蜀,在訂閱者出現(xiàn)之前會(huì)持有數(shù)據(jù)召耘,在訂閱者出現(xiàn)之后就才轉(zhuǎn)交給它。而廣播類(lèi)似于發(fā)布訂閱模式褐隆,可以同時(shí)有多個(gè)訂閱者怎茫,當(dāng)有數(shù)據(jù)時(shí)就會(huì)傳遞給所有的訂閱者,而不管當(dāng)前是否已有訂閱者存在妓灌。
Stream
默認(rèn)處于單訂閱模式轨蛤,所以同一個(gè) stream 上的 listen 和其它大多數(shù)方法只能調(diào)用一次,調(diào)用第二次就會(huì)報(bào)錯(cuò)虫埂。但 Stream 可以通過(guò)
transform() 方法(返回另一個(gè) Stream)進(jìn)行連續(xù)調(diào)用祥山。通過(guò) Stream.asBroadcastStream()
可以將一個(gè)單訂閱模式的 Stream 轉(zhuǎn)換成一個(gè)多訂閱模式的 Stream,isBroadcast 屬性可以判斷當(dāng)前 Stream 所處的模式掉伏。
8. await for 如何使用缝呕?
await for是不斷獲取stream流中的數(shù)據(jù),然后執(zhí)行循環(huán)體中的操作斧散。它一般用在直到stream什么時(shí)候完成供常,并且必須等待傳遞完成之后才能使用,不然就會(huì)一直阻塞鸡捐。
Stream<String> stream = new Stream<String>.fromIterable(['不開(kāi)心', '面試', '沒(méi)', '過(guò)']);
main() async{
? ? await for(String s in stream){
? ? print(s);
? }
}
9. 說(shuō)一下 mixin機(jī)制栈暇?
mixin 是Dart 2.1 加入的特性,以前版本通常使用abstract class代替箍镜。簡(jiǎn)單來(lái)說(shuō)源祈,mixin是為了解決繼承方面的問(wèn)題而引入的機(jī)制,Dart為了支持多重繼承色迂,引入了mixin關(guān)鍵字香缺,它最大的特殊處在于:mixin定義的類(lèi)不能有構(gòu)造方法,這樣可以避免繼承多個(gè)類(lèi)而產(chǎn)生的父類(lèi)構(gòu)造方法沖突歇僧。
mixins的對(duì)象是類(lèi)图张,mixins絕不是繼承,也不是接口,而是一種全新的特性祸轮,可以mixins多個(gè)類(lèi)姑隅,mixins的使用需要滿(mǎn)足一定條件。
Flutter
1. 下Flutter框架倔撞,以及它的優(yōu)缺點(diǎn)?
Flutter是Google推出的一套開(kāi)源跨平臺(tái)UI框架慕趴,可以快速地在Android痪蝇、iOS和Web平臺(tái)上構(gòu)建高質(zhì)量的原生用戶(hù)界面。同時(shí)冕房,F(xiàn)lutter還是Google新研發(fā)的Fuchsia操作系統(tǒng)的默認(rèn)開(kāi)發(fā)套件躏啰。在全世界,F(xiàn)lutter正在被越來(lái)越多的開(kāi)發(fā)者和組織使用耙册,并且Flutter是完全免費(fèi)给僵、開(kāi)源的。Flutter采用現(xiàn)代響應(yīng)式框架構(gòu)建详拙,其中心思想是使用組件來(lái)構(gòu)建應(yīng)用的UI帝际。當(dāng)組件的狀態(tài)發(fā)生改變時(shí),組件會(huì)重構(gòu)它的描述饶辙,F(xiàn)lutter會(huì)對(duì)比之前的描述蹲诀,以確定底層渲染樹(shù)從當(dāng)前狀態(tài)轉(zhuǎn)換到下一個(gè)狀態(tài)所需要的最小更改。
優(yōu)點(diǎn)
熱重載(Hot Reload)弃揽,利用Android Studio直接一個(gè)ctrl+s就可以保存并重載脯爪,模擬器立馬就可以看見(jiàn)效果,相比原生冗長(zhǎng)的編譯過(guò)程強(qiáng)很多矿微;
一切皆為Widget的理念痕慢,對(duì)于Flutter來(lái)說(shuō),手機(jī)應(yīng)用里的所有東西都是Widget涌矢,通過(guò)可組合的空間集合掖举、豐富的動(dòng)畫(huà)庫(kù)以及分層課擴(kuò)展的架構(gòu)實(shí)現(xiàn)了富有感染力的靈活界面設(shè)計(jì);
借助可移植的GPU加速的渲染引擎以及高性能本地代碼運(yùn)行時(shí)以達(dá)到跨平臺(tái)設(shè)備的高質(zhì)量用戶(hù)體驗(yàn)娜庇。簡(jiǎn)單來(lái)說(shuō)就是:最終結(jié)果就是利用Flutter構(gòu)建的應(yīng)用在運(yùn)行效率上會(huì)和原生應(yīng)用差不多拇泛。
缺點(diǎn)
不支持熱更新;
三方庫(kù)有限思灌,需要自己造輪子俺叭;
Dart語(yǔ)言編寫(xiě),增加了學(xué)習(xí)難度泰偿,并且學(xué)習(xí)了Dart之后無(wú)其他用處熄守,相比JS和Java來(lái)說(shuō)。
2. 介紹下Widget、State裕照、Context 概念
Widget:在Flutter中攒发,幾乎所有東西都是Widget。將一個(gè)Widget想象為一個(gè)可視化的組件(或與應(yīng)用可視化方面交互的組件)晋南,當(dāng)你需要構(gòu)建與布局直接或間接相關(guān)的任何內(nèi)容時(shí)惠猿,你正在使用Widget。
Widget樹(shù):Widget以樹(shù)結(jié)構(gòu)進(jìn)行組織负间。包含其他Widget的widget被稱(chēng)為父Widget(或widget容器)偶妖。包含在父widget中的widget被稱(chēng)為子Widget。
Context:僅僅是已創(chuàng)建的所有Widget樹(shù)結(jié)構(gòu)中的某個(gè)Widget的位置引用政溃。簡(jiǎn)而言之趾访,將context作為widget樹(shù)的一部分,其中context所對(duì)應(yīng)的widget被添加到此樹(shù)中董虱。一個(gè)context只從屬于一個(gè)widget扼鞋,它和widget一樣是鏈接在一起的,并且會(huì)形成一個(gè)context樹(shù)愤诱。
State:定義了StatefulWidget實(shí)例的行為云头,它包含了用于”交互/干預(yù)“Widget信息的行為和布局。應(yīng)用于State的任何更改都會(huì)強(qiáng)制重建Widget淫半。
3. 簡(jiǎn)述Widget的StatelessWidget和StatefulWidget兩種狀態(tài)組件類(lèi)
StatelessWidget: 一旦創(chuàng)建就不關(guān)心任何變化盘寡,在下次構(gòu)建之前都不會(huì)改變。它們除了依賴(lài)于自身的配置信息(在父節(jié)點(diǎn)構(gòu)建時(shí)提供)外不再依賴(lài)于任何其他信息撮慨。比如典型的Text竿痰、Row、Column砌溺、Container等影涉,都是StatelessWidget。它的生命周期相當(dāng)簡(jiǎn)單:初始化规伐、通過(guò)build()渲染蟹倾。
StatefulWidget: 在生命周期內(nèi),該類(lèi)Widget所持有的數(shù)據(jù)可能會(huì)發(fā)生變化猖闪,這樣的數(shù)據(jù)被稱(chēng)為State鲜棠,這些擁有動(dòng)態(tài)內(nèi)部數(shù)據(jù)的Widget被稱(chēng)為StatefulWidget。比如復(fù)選框培慌、Button等豁陆。State會(huì)與Context相關(guān)聯(lián),并且此關(guān)聯(lián)是永久性的吵护,State對(duì)象將永遠(yuǎn)不會(huì)改變其Context盒音,即使可以在樹(shù)結(jié)構(gòu)周?chē)苿?dòng)表鳍,也仍將與該context相關(guān)聯(lián)。當(dāng)state與context關(guān)聯(lián)時(shí)祥诽,state被視為已掛載譬圣。StatefulWidget由兩部分組成,在初始化時(shí)必須要在createState()時(shí)初始化一個(gè)與之相關(guān)的State對(duì)象雄坪。
4. StatefulWidget 的生命周期
Flutter的Widget分為StatelessWidget和StatefulWidget兩種厘熟。其中,StatelessWidget是無(wú)狀態(tài)的维哈,StatefulWidget是有狀態(tài)的绳姨,因此實(shí)際使用時(shí),更多的是StatefulWidget笨农。
initState():Widget 初始化當(dāng)前 State,在當(dāng)前方法中是不能獲取到 Context 的帖渠,如想獲取谒亦,可以試試 Future.delayed()
didChangeDependencies():在 initState() 后調(diào)用,State對(duì)象依賴(lài)關(guān)系發(fā)生變化的時(shí)候也會(huì)調(diào)用空郊。
deactivate():當(dāng) State 被暫時(shí)從視圖樹(shù)中移除時(shí)會(huì)調(diào)用這個(gè)方法份招,頁(yè)面切換時(shí)也會(huì)調(diào)用該方法,和Android里的 onPause 差不多狞甚。
dispose():Widget 銷(xiāo)毀時(shí)調(diào)用锁摔。
didUpdateWidget:Widget 狀態(tài)發(fā)生變化的時(shí)候調(diào)用。
5. 簡(jiǎn)述Widgets哼审、RenderObjects 和 Elements的關(guān)系
首先看一下這幾個(gè)對(duì)象的含義及作用谐腰。
Widget:僅用于存儲(chǔ)渲染所需要的信息。
RenderObject:負(fù)責(zé)管理布局涩盾、繪制等操作十气。
Element:才是這顆巨大的控件樹(shù)上的實(shí)體。
Widget會(huì)被inflate(填充)到Element春霍,并由Element管理底層渲染樹(shù)砸西。Widget并不會(huì)直接管理狀態(tài)及渲染,而是通過(guò)State這個(gè)對(duì)象來(lái)管理狀態(tài)。Flutter創(chuàng)建Element的可見(jiàn)樹(shù)址儒,相對(duì)于Widget來(lái)說(shuō)芹枷,是可變的,通常界面開(kāi)發(fā)中莲趣,我們不用直接操作Element,而是由框架層實(shí)現(xiàn)內(nèi)部邏輯鸳慈。就如一個(gè)UI視圖樹(shù)中,可能包含有多個(gè)TextWidget(Widget被使用多次)喧伞,但是放在內(nèi)部視圖樹(shù)的視角蝶涩,這些TextWidget都是填充到一個(gè)個(gè)獨(dú)立的Element中理朋。Element會(huì)持有renderObject和widget的實(shí)例。記住绿聘,Widget
只是一個(gè)配置嗽上,RenderObject 負(fù)責(zé)管理布局、繪制等操作熄攘。
在第一次創(chuàng)建 Widget 的時(shí)候兽愤,會(huì)對(duì)應(yīng)創(chuàng)建一個(gè) Element, 然后將該元素插入樹(shù)中挪圾。如果之后 Widget 發(fā)生了變化浅萧,則將其與舊的 Widget 進(jìn)行比較,并且相應(yīng)地更新 Element哲思。重要的是洼畅,Element 不會(huì)被重建,只是更新而已棚赔。
6. 什么是狀態(tài)管理帝簇,你了解哪些狀態(tài)管理框架?
Flutter中的狀態(tài)和前端React中的狀態(tài)概念是一致的靠益。React框架的核心思想是組件化丧肴,應(yīng)用由組件搭建而成,組件最重要的概念就是狀態(tài)胧后,狀態(tài)是一個(gè)組件的UI數(shù)據(jù)模型芋浮,是組件渲染時(shí)的數(shù)據(jù)依據(jù)。
Flutter的狀態(tài)可以分為全局狀態(tài)和局部狀態(tài)兩種壳快。常用的狀態(tài)管理有ScopedModel纸巷、BLoC、Redux / FishRedux和Provider眶痰。詳細(xì)使用情況和差異可以自行了解何暇。
7. Flutter 是如何與原生Android、iOS進(jìn)行通信的凛驮?
Flutter 通過(guò) PlatformChannel 與原生進(jìn)行交互裆站,其中 PlatformChannel 分為三種:
BasicMessageChannel:用于傳遞字符串和半結(jié)構(gòu)化的信息。
MethodChannel:用于傳遞方法調(diào)用(method invocation)黔夭。
EventChannel: 用于數(shù)據(jù)流(event streams)的通信宏胯。