Flutter知識點(diǎn)

Flutter

1 Flutter是什么冈欢?

Flutter是谷歌的移動UI框架缘挑,可以快速在iOS和Android上構(gòu)建高質(zhì)量的原生用戶界面鹰贵。 Flutter可以與現(xiàn)有的代碼一起工作。在全世界艘绍,F(xiàn)lutter正在被越來越多的開發(fā)者和組織使用蚊荣,并且Flutter是完全免費(fèi)初狰、開源的。

優(yōu)點(diǎn)

  • 熱重載(Hot Reload)互例,利用Android Studio直接一個ctrl+s就可以保存并重載奢入,模擬器立馬就可以看見效果,相比原生慢長的編譯過程強(qiáng)很多媳叨;
  • 一切皆為Widget的理念腥光,對于Flutter來說,手機(jī)應(yīng)用里的所有東西都是Widget糊秆,通過可組合的空間集合武福、豐富的動畫庫以及分層擴(kuò)展的架構(gòu)實現(xiàn)了富有感染力的靈活界面設(shè)計;
  • 借助可移植的GPU加速的渲染引擎以及高性能本地代碼運(yùn)行時以達(dá)到跨平臺設(shè)備的高質(zhì)量用戶體驗痘番。 簡單來說就是:最終結(jié)果就是利用Flutter構(gòu)建的應(yīng)用在運(yùn)行效率上會和原生應(yīng)用差不多捉片。

缺點(diǎn)

  • 不支持熱更新;
  • 三方庫有限汞舱,需要自己造輪子伍纫;
  • Dart語言編寫,增加了學(xué)習(xí)難度昂芜,并且學(xué)習(xí)了Dart之后無其他用處莹规,相比JS和Java來說。

2 Flutter特性有那些泌神?

1 跨平臺

2 熱重載良漱。

3 Flutter 中的生命周期

  1. initState:插入渲染樹時調(diào)用,只調(diào)用一次腻扇,widget創(chuàng)建執(zhí)行的第一個方法债热,可以再里面初始化一些數(shù)據(jù),以及綁定控制器幼苛。

  2. didChangeDependencies:在 initState() 后調(diào)用窒篱。當(dāng)State對象的依賴發(fā)生變化時會被調(diào)用;例如:在之前build() 中包含了一個InheritedWidget舶沿,然后在之后的build() 中InheritedWidget發(fā)生了變化墙杯,那么此時InheritedWidget的子widget的didChangeDependencies()回調(diào)都會被調(diào)用。InheritedWidget這個widget可以由父控件向子控件共享數(shù)據(jù)括荡,案例可以參考 scoped_model開源庫高镐。

  3. build :它主要是用于構(gòu)建Widget子樹的,調(diào)用次數(shù):多次畸冲,初始化之后開始繪制界面嫉髓,當(dāng)setState觸發(fā)的時候會再次被調(diào)用

  4. didUpdateWidget:組件狀態(tài)改變時候調(diào)用观腊,可能會調(diào)用多次

  5. deactivate:當(dāng)State對象從樹中被移除時,會調(diào)用此回調(diào)算行。

  6. dispose():當(dāng)State對象從樹中被永久移除時調(diào)用梧油;通常在此回調(diào)中釋放資源。

  7. reassemble:此回調(diào)是專門為了開發(fā)調(diào)試而提供的州邢,在熱重載(hot reload)時會被調(diào)用儡陨,此回調(diào)在Release模式下永遠(yuǎn)不會被調(diào)用。

4 flutter widget量淌、Element骗村、 RenderObject關(guān)系

· Widget實際上就是Element的配置數(shù)據(jù),Widget樹實際上是一個配置樹呀枢,而真正的UI渲染樹是由Element構(gòu)成胚股;不過,由于Element是通過Widget生成硫狞,所以它們之間有對應(yīng)關(guān)系信轿,所以在大多數(shù)場景,我們可以寬泛地認(rèn)為Widget樹就是指UI控件樹或UI渲染樹残吩。

· 一個Widget對象可以對應(yīng)多個Element對象财忽。這很好理解,根據(jù)同一份配置(Widget)泣侮,可以創(chuàng)建多個實例(Element)即彪。

· 從創(chuàng)建到渲染的大體流程是:根據(jù)Widget生成Element,然后創(chuàng)建相應(yīng)的RenderObject并關(guān)聯(lián)到Element.renderObject屬性上活尊,最后再通過RenderObject來完成布局排列和繪制隶校。

flutter使用RenderObjects管理傳統(tǒng)UI對象的許多職責(zé)(例如維護(hù)布局的狀態(tài))。RenderObjects在幀之間保持不變蛹锰,flutter的輕量級Widgets告訴框架在狀態(tài)之間改變RenderObjects深胳。

· Widget 僅用于存儲渲染所需要的信息。

· RenderObject 負(fù)責(zé)管理布局铜犬、繪制等操作舞终。

· Element 才是這顆巨大的控件樹上的實體。

Layer

iOS的每一個UIView都有一個layer癣猾,flutter的render object不一定存在layer敛劝,一般情況下一個renderObject子樹都渲染在一個layer上,那么什么renderObject具有l(wèi)ayer纷宇,子renderObject怎么渲染到這個layer夸盟?

  • 當(dāng)一個renderObject的 alwaysNeedsCompositing == true 或者isRepaintBoundary == true,renderOject會有對應(yīng)的compositing layer
  • 子renderObject會對目標(biāo)layer返回對應(yīng)的offsetLayer, 目標(biāo)compositing layer再根據(jù)offset合成一個渲染的紋理buffer

5 didChangeDependencies有兩種情況會被調(diào)用像捶。

1 創(chuàng)建時候在initState 之后被調(diào)用

2 在依賴的InheritedWidget發(fā)生變化的時候會被調(diào)

6 Flutter跟ReactNative上陕、weex 等有什么不同桩砰?

1 WebViews 最早的跨平臺方案是基于JaveScript 和 WebView的,像PhoneGap唆垃、Cordova五芝、Ionic等痘儡。UI通過WebView來顯示html代碼辕万,系統(tǒng)服務(wù)則通過一個中間層橋接到JaveScript中去。

2 原生App

蘋果2008年發(fā)布iOS沉删,Google 2009年發(fā)布Android渐尿,它們的SDK是基于兩種不同的編程語言O(shè)bjective-C 和 Jave.現(xiàn)在又有了Swift和Kotlin

3 React Native RN不僅橋接系統(tǒng)服務(wù),也將系統(tǒng)UI也橋接到了JaveScript中矾瑰,這樣寫出來的UI最終也會渲染成原生的控件砖茸。

4 Flutter Flutter使用Dart語言開發(fā),Dart可以被編譯(AOT)成不同平臺的本地代碼殴穴,讓Flutter可以直接和平臺通訊而不需要一個中間的橋接過程凉夯,從而提高了性能。

7 Widget的兩種類型是什么采幌?

1 StatelessWidget: 一旦創(chuàng)建就不關(guān)心任何變化劲够,在下次構(gòu)建之前都不會改變。它們除了依賴于自身的配置信息(在父節(jié)點(diǎn)構(gòu)建時提供)外不再依賴于任何其他信息休傍。比如典型的Text征绎、Row、Column磨取、Container等人柿,都是StatelessWidget。它的生命周期相當(dāng)簡單:初始化忙厌、通過build()渲染凫岖。

2 StatefulWidget: 在生命周期內(nèi),該類Widget所持有的數(shù)據(jù)可能會發(fā)生變化逢净,這樣的數(shù)據(jù)被稱為State哥放,這些擁有動態(tài)內(nèi)部數(shù)據(jù)的Widget被稱為StatefulWidget。比如復(fù)選框汹胃、Button等婶芭。State會與Context相關(guān)聯(lián),并且此關(guān)聯(lián)是永久性的着饥,State對象將永遠(yuǎn)不會改變其Context犀农,即使可以在樹結(jié)構(gòu)周圍移動,也仍將與該context相關(guān)聯(lián)宰掉。當(dāng)state與context關(guān)聯(lián)時呵哨,state被視為已掛載赁濒。StatefulWidget由兩部分組成,在初始化時必須要在createState()時初始化一個與之相關(guān)的State對象

8 Flutter 和 Dart的關(guān)系是什么孟害?

   Flutter是一個使用Dart語言開發(fā)的跨平臺移動UI框架拒炎,通過自建繪制引擎,能提高性能挨务、高保真地進(jìn)行移動開發(fā)击你。Dart囊括了多數(shù)編程語言的優(yōu)點(diǎn),它更符合Flutter構(gòu)建界面的方式

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

繼承(關(guān)鍵字 extends)谎柄、混入 mixins (關(guān)鍵字 with)丁侄、接口實現(xiàn)(關(guān)鍵字 implements)。這三者可以同時存在朝巫,前后順序是extends -> mixins -> implements鸿摇。

Flutter中的繼承是單繼承,子類重寫超類的方法要用@Override劈猿,子類調(diào)用超類的方法要用super拙吉。

在Flutter中,Mixins是一種在多個類層次結(jié)構(gòu)中復(fù)用類代碼的方法揪荣。mixins的對象是類筷黔,mixins絕不是繼承,也不是接口变逃,而是一種全新的特性必逆,可以mixins多個類,mixins的使用需要滿足一定條件揽乱。

10 什么是Navigator? MaterialApp做了什么名眉?

Navigator是在Flutter中負(fù)責(zé)管理維護(hù)頁面堆棧的導(dǎo)航器。MaterialApp在需要的時候凰棉,會自動為我們創(chuàng)建Navigator损拢。Navigator.of(context),會使用context來向上遍歷Element樹撒犀,找到MaterialApp提供的_NavigatorState再調(diào)用其push/pop方法完成導(dǎo)航操作福压。

11 Widget 唯一標(biāo)識Key有那幾種?

在flutter中或舞,每個widget都是被唯一標(biāo)識的荆姆。這個唯一標(biāo)識在build或rendering階段由框架定義。該標(biāo)識對應(yīng)于可選的Key參數(shù)映凳,如果省略胆筒,F(xiàn)lutter將會自動生成一個。

在flutter中,主要有4種類型的Key:GlobalKey(確保生成的Key在整個應(yīng)用中唯一仆救,是很昂貴的抒和,允許element在樹周圍移動或變更父節(jié)點(diǎn)而不會丟失狀態(tài))、LocalKey彤蔽、UniqueKey摧莽、ObjectKey。

12 Future和Isolate有什么區(qū)別顿痪?

future是異步編程镊辕,調(diào)用本身立即返回,并在稍后的某個時候執(zhí)行完成時再獲得返回結(jié)果员魏。在普通代碼中可以使用await 等待一個異步調(diào)用結(jié)束丑蛤。

isolate是并發(fā)編程,Dartm有并發(fā)時的共享狀態(tài)撕阎,所有Dart代碼都在isolate中運(yùn)行,包括最初的main()碌补。每個isolate都有它自己的堆內(nèi)存虏束,意味著其中所有內(nèi)存數(shù)據(jù),包括全局?jǐn)?shù)據(jù)厦章,都僅對該isolate可見镇匀,它們之間的通信只能通過傳遞消息的機(jī)制完成,消息則通過端口(port)收發(fā)袜啃。isolate只是一個概念汗侵,具體取決于如何實現(xiàn),比如在Dart VM中一個isolate可能會是一個線程群发,在Web中可能會是一個Web Worker晰韵。

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

Stream 和 Future 是 Dart 異步處理的核心 API熟妓。Future 表示稍后獲得的一個數(shù)據(jù)雪猪,所有異步的操作的返回值都用 Future 來表示。但是 Future 只能表示一次異步獲得的數(shù)據(jù)起愈。而 Stream 表示多次異步獲得的數(shù)據(jù)只恨。比如界面上的按鈕可能會被用戶點(diǎn)擊多次,所以按鈕上的點(diǎn)擊事件(onClick)就是一個 Stream 抬虽。簡單地說官觅,F(xiàn)uture將返回一個值,而Stream將返回多次值阐污。Dart 中統(tǒng)一使用 Stream 處理異步事件流休涤。Stream 和一般的集合類似,都是一組數(shù)據(jù)疤剑,只不過一個是異步推送滑绒,一個是同步拉取闷堡。

14 await for 如何使用?

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

15 Flutter的架構(gòu)主要分成三層:Framework踱阿,Engine和Embedder。

Framework使用dart實現(xiàn)钦铁,包括Material Design風(fēng)格的Widget,Cupertino(針對iOS)風(fēng)格的Widgets软舌,文本/圖片/按鈕等基礎(chǔ)Widgets、渲染牛曹、動畫佛点、手勢等。此部分的核心代碼是:flutter倉庫下的flutter package黎比,以及sky_engine倉庫下的io,async,ui(dart:ui庫提供了Flutter框架和引擎之間的接口)等package超营。

Engine使用C++實現(xiàn),主要包括:Skia,Dart和Text阅虫。Skia是開源的二維圖形庫演闭,提供了適用于多種軟硬件平臺的通用API。其已作為Google Chrome颓帝,Chrome OS米碰,Android, Mozilla Firefox, Firefox OS等其他眾多產(chǎn)品的圖形引擎,支持平臺還包括Windows7+,macOS 10.10.5+,iOS8+,Android4.1+,Ubuntu14.04+等购城。

Dart部分主要包括:Dart Runtime吕座,Garbage Collection(GC),如果是Debug模式的話工猜,還包括JIT(Just In Time)支持米诉。Release和Profile模式下,是AOT(Ahead Of Time)編譯成了原生的arm代碼篷帅,并不存在JIT部分史侣。Text即文本渲染,其渲染層次如下:衍生自minikin的libtxt庫(用于字體選擇魏身,分隔行)惊橱。HartBuzz用于字形選擇和成型。Skia作為渲染/GPU后端箭昵,在Android和Fuchsia上使用FreeType渲染税朴,在iOS上使用CoreGraphics來渲染字體。

Embedder是一個嵌入層,即把Flutter嵌入到各個平臺上去正林,這里做的主要工作包括渲染Surface設(shè)置,線程設(shè)置泡一,以及插件等。從這里可以看出觅廓,F(xiàn)lutter的平臺相關(guān)層很低鼻忠,平臺(如iOS)只是提供一個畫布,剩余的所有渲染相關(guān)的邏輯都在Flutter內(nèi)部杈绸,這就使得它具有了很好的跨端一致性帖蔓。

16 Flutter 如何與 Android iOS 通信?

Flutter與原生系統(tǒng)主要有三種通信形式:MethodChannel和EventChannel及BasicMessageChannel瞳脓。

1 BasicMessageChannel:用于傳遞字符串和半結(jié)構(gòu)化的信息塑娇,持續(xù)通信,收到消息后可以回復(fù)此次消息劫侧,如:Native將遍歷到的文件信息陸續(xù)傳遞到Dart埋酬,在比如:Flutter將從服務(wù)端陸續(xù)獲取到信息交給Native加工,Native處理完返回等板辽;

2 MethodChannel:用于傳遞方法調(diào)用奇瘦。(method invocation)一次性通信:如Flutter調(diào)用Native拍照;

3 EventChannel: 用于數(shù)據(jù)流(event streams)的通信劲弦,持續(xù)通信,收到消息后無法回復(fù)此次消息醇坝,通常用于Native向Dart的通信邑跪,如:手機(jī)電量變化,網(wǎng)絡(luò)連接變化呼猪,陀螺儀画畅,傳感器等;

這三種類型的類型的Channel都是全雙工通信宋距,即A <=> B轴踱,Dart可以主動發(fā)送消息給platform端,并且platform接收到消息后可以做出回應(yīng)谚赎,同樣淫僻,platform端可以主動發(fā)送消息給Dart端,dart端接收數(shù)后返回給platform端壶唤。

17 Flutter中的Widget雳灵、State、Context 的核心概念闸盔?是為了解決什么問題悯辙?

1 Widget: 在Flutter中,幾乎所有東西都是Widget。將一個Widget想象為一個可視化的組件(或與應(yīng)用可視化方面交互的組件)躲撰,當(dāng)你需要構(gòu)建與布局直接或間接相關(guān)的任何內(nèi)容時针贬,你正在使用Widget。

2 Widget樹: Widget以樹結(jié)構(gòu)進(jìn)行組織拢蛋。包含其他Widget的widget被稱為父Widget(或widget容器)桦他。包含在父widget中的widget被稱為子Widget。

3 Context: 僅僅是已創(chuàng)建的所有Widget樹結(jié)構(gòu)中的某個Widget的位置引用瓤狐。簡而言之瞬铸,將context作為widget樹的一部分,其中context所對應(yīng)的widget被添加到此樹中础锐。一個context只從屬于一個widget嗓节,它和widget一樣是鏈接在一起的,并且會形成一個context樹皆警。

4 State: 定義了StatefulWidget實例的行為拦宣,它包含了用于”交互/干預(yù)“Widget信息的行為和布局。應(yīng)用于State的任何更改都會強(qiáng)制重建Widget信姓。

5 這些狀態(tài)的引入鸵隧,主要是為了解決多個部件之間的交互和部件自身狀態(tài)的維護(hù)。

18 ****Dart****部分**

19 Dart是值傳遞還是引用傳遞

dart是值傳遞意推。

20 Dart 當(dāng)中的 「..」表示什么意思豆瘫?

Dart 當(dāng)中的 「..」意思是 「級聯(lián)操作符」,為了方便配置而使用菊值。

「..」和「.」不同的是 調(diào)用「..」后返回的相當(dāng)于是 this外驱,而「.」返回的則是該方法返回的值 。

21 Dart 的作用域

Dart 沒有 「public」「private」等關(guān)鍵字腻窒,默認(rèn)就是公開的昵宇,私有變量使用 下劃線 _開頭

22 Dart 是不是單線程模型?是如何運(yùn)行的儿子?

Dart 是單線程模型瓦哎,如何運(yùn)行的看這張圖:

[圖片上傳失敗...(image-cff6d3-1598350597924)]

Dart 在單線程中是以消息循環(huán)機(jī)制來運(yùn)行的,其中包含兩個任務(wù)隊列柔逼,一個是“微任務(wù)隊列” microtask queue蒋譬,另一個叫做“事件隊列” event queue。

入口函數(shù) main() 執(zhí)行完后卒落,消息循環(huán)機(jī)制便啟動了羡铲。首先會按照先進(jìn)先出的順序逐個執(zhí)行微任務(wù)隊列中的任務(wù),當(dāng)所有微任務(wù)隊列執(zhí)行完后便開始執(zhí)行事件隊列中的任務(wù)儡毕,事件任務(wù)執(zhí)行完畢后再去執(zhí)行微任務(wù)也切,如此循環(huán)往復(fù)扑媚,生生不息。

23 final 和 const區(qū)別

const 的值在編譯期確定雷恃,final 的值要到運(yùn)行時才確定

24 說一下Dart異步編程中的 Stream數(shù)據(jù)流疆股?

在Dart中,Stream 和 Future 一樣倒槐,都是用來處理異步編程的工具旬痹。它們的區(qū)別在于,Stream 可以接收多個異步結(jié)果讨越,而Future 只有一個两残。Stream 的創(chuàng)建可以使用 Stream.fromFuture,也可以使用 StreamController 來創(chuàng)建和控制把跨。還有一個注意點(diǎn)是:普通的Stream 只可以有一個訂閱者人弓,如果想要多訂閱的話,要使用 asBroadcastStream()着逐。

25 App 打包上傳

在flutter項目中分別打開 Android和IOS 文件崔赌,和原生開發(fā)方式的打包上架形式是一樣的。

命令打包

cd 到文件目錄

iOS:Flutter Build ios –-release

Android : flutter build apk –release

26 啟動頁和圖標(biāo)耸别,添加方式和iOS健芭,android原有的方式一樣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秀姐,一起剝皮案震驚了整個濱河市慈迈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌省有,老刑警劉巖吩翻,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锥咸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)细移,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門搏予,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弧轧,你說我怎么就攤上這事雪侥。” “怎么了精绎?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵速缨,是天一觀的道長。 經(jīng)常有香客問我代乃,道長旬牲,這世上最難降的妖魔是什么仿粹? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮原茅,結(jié)果婚禮上吭历,老公的妹妹穿的比我還像新娘。我一直安慰自己擂橘,他們只是感情好晌区,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著通贞,像睡著了一般朗若。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上昌罩,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天哭懈,我揣著相機(jī)與錄音,去河邊找鬼峡迷。 笑死银伟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绘搞。 我是一名探鬼主播彤避,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼夯辖!你這毒婦竟也來了琉预?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蒿褂,失蹤者是張志新(化名)和其女友劉穎圆米,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啄栓,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娄帖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了昙楚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片近速。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖堪旧,靈堂內(nèi)的尸體忽然破棺而出削葱,到底是詐尸還是另有隱情,我是刑警寧澤淳梦,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布析砸,位于F島的核電站,受9級特大地震影響爆袍,放射性物質(zhì)發(fā)生泄漏首繁。R本人自食惡果不足惜作郭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛮瞄。 院中可真熱鬧所坯,春花似錦、人聲如沸挂捅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闲先。三九已至状土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伺糠,已是汗流浹背蒙谓。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留训桶,地道東北人累驮。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像舵揭,于是被迫代替她去往敵國和親谤专。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359