Flutter 開發(fā)實(shí)戰(zhàn)與前景展望 - RTC Dev Meetup

大家好坠七,我是郭樹煜毒嫡,Github GSY 系列開源項(xiàng)目的作者莹妒,系列包括有 GSYVideoPlayer 、GSYGitGithubApp(Flutter\ReactNative\Kotlin\Weex)四大版本诈茧,目前總 star 在 17
k+ 左右,主要活躍在掘金社區(qū)捂掰,id 是戀貓的小郭敢会,主要專欄有《Flutter完整開發(fā)實(shí)戰(zhàn)詳解》系列等,平時(shí)工作負(fù)責(zé)移動(dòng)端項(xiàng)目的開發(fā)这嚣,工作經(jīng)歷從 Android 到 React Native 鸥昏、Weex 再到如今的 Flutter ,期間也參與過(guò) React 疤苹、 Vue 互广、小程序等相關(guān)的開發(fā),算是一個(gè)大前端的選手吧。

這次主要是給大家分享 Flutter 相關(guān)的內(nèi)容惫皱,主要涉及做一些實(shí)戰(zhàn)和科普性質(zhì)的內(nèi)容像樊。

image

一、移動(dòng)開發(fā)的現(xiàn)狀

恰逢最近谷歌 IO 大會(huì)結(jié)束旅敷,大會(huì)后也在線上線下和大家有過(guò)交流生棍,總結(jié)了下大家最關(guān)系的問(wèn)題有:

1、谷歌在 Kotlin-First 的口號(hào)下又推廣 Dart + Flutter 沖突嗎媳谁?

這個(gè)問(wèn)題算是被問(wèn)得最多的一個(gè)涂滴,先說(shuō)觀點(diǎn):我個(gè)人認(rèn)為其實(shí)這并不沖突,因?yàn)橛袀€(gè) 誤區(qū)就是認(rèn)為跨平臺(tái)開發(fā)就可以拋棄原生開發(fā)晴音!

如果從事過(guò)跨平臺(tái)開發(fā)的同學(xué)應(yīng)該知道柔纵,平臺(tái)提供的功能向來(lái)是有限的,而面對(duì)產(chǎn)品經(jīng)理的各種 “點(diǎn)歪技能樹” 的需求锤躁,很多時(shí)候你是需要基于框架外提供支持搁料,常見的就是 混合開發(fā)或者原生插件支持

所以這里我表達(dá)的是系羞,目前 KotlinDart 更多是相輔相成 郭计,而一旦業(yè)務(wù)復(fù)雜度到一定程度,跨平臺(tái)框架還可能存在降低工作效率的問(wèn)題椒振,比如針對(duì)新需求昭伸,需要重復(fù)開發(fā) Android/IOS 的原生插件做支持,這也是 Aribnb 曾經(jīng)選擇放棄 React Native 的原因之一澎迎。

與我而言庐杨,跨平臺(tái)的意義在于解決的是端邏輯的統(tǒng)一 ,至少避免了邏輯重復(fù)實(shí)現(xiàn)嗡善,或者 IOSAndroid 之間爭(zhēng)論 誰(shuí)對(duì)誰(shuí)錯(cuò) 的問(wèn)題辑莫,甚至可以統(tǒng)一到 web 端等等。

image

2罩引、React Native 和 Flutter 之間的對(duì)比

Flutter 作為后來(lái)者各吨,難免會(huì)被用來(lái)和 React Native 進(jìn)行對(duì)比,在這個(gè)萬(wàn)物皆是 JS 的時(shí)代袁铐,DartFlutter 的出現(xiàn)顯得尤為扎眼揭蜒。

在設(shè)計(jì)上它們有著許多相似之處,響應(yīng)式設(shè)計(jì)/async支持/setState更新 等等剔桨,同時(shí)也有著各種的差異屉更,而大家最為關(guān)心的,無(wú)非 性能洒缀、支持瑰谜、上手難易欺冀、穩(wěn)定性程度 這四方面:

  • 性能上 Flutter 的確實(shí)會(huì)比 React Native 好 ,如下圖所示萨脑,這是由框架底層決定的隐轩,當(dāng)然目前 React Native 也在進(jìn)行下一代的優(yōu)化, 而對(duì)此最直觀的數(shù)據(jù)就是:GSY系列 在18年用于閑魚測(cè)試下的對(duì)比數(shù)據(jù)了 渤早。
image10.png
image11.png

同時(shí)注意不要用模擬器測(cè)試性能职车,特別是IOS模擬器做性能測(cè)試,因?yàn)?Flutter 在 IOS模擬器中純 CPU 鹊杖,而實(shí)際設(shè)備會(huì)是 GPU 硬件加速悴灵,同時(shí)只在 Release 下對(duì)比性能。

  • 支持上 Flutter 和 React Native 骂蓖, 都存在第三方包質(zhì)量參差不齊的問(wèn)題积瞒,而目前在這一塊 Flutter 是弱于 React Native 的 ,畢竟 React Native 發(fā)展已久登下,雖然版本號(hào)一直不到 1.0赡鲜,但是在 JS 的加持下生態(tài)豐富,同時(shí)也是因?yàn)槠脚_(tái)特性的原因庐船,諸如 WebView 、地圖等控件的支持上現(xiàn)在依舊不夠好嘲更,這個(gè)后面也會(huì)說(shuō)道筐钟。

  • 上手難易度上,Flutter 配置環(huán)境和運(yùn)行的“成功率”比 React Native 高不少 赋朦,這里面有 node_module 黑洞這個(gè)坑篓冲,也有 React Native 本身依賴平臺(tái)控件導(dǎo)致的,至少我曾經(jīng)試過(guò)接手一個(gè) React Native 跑了一天都沒跑起來(lái)的經(jīng)歷宠哄,同時(shí) Flutter 在運(yùn)行和SDK版本升級(jí)的陣痛也會(huì)少很多壹将。

  • 穩(wěn)定性:Flutter 中大部分異常是不會(huì)引起應(yīng)用崩潰 ,更多會(huì)在 Debug 上體現(xiàn)為紅色錯(cuò)誤堆棧毛嫉,Release 上 UI 異常等等诽俯。

如果你是前端,我會(huì)推薦你先學(xué) React Native承粤,如果你是原生開發(fā)暴区,我推薦你學(xué) Flutter 鹊奖。

在 React Native 0.59.x 版本開始偏形,React 已經(jīng)將許多內(nèi)置控件和庫(kù)移出主項(xiàng)目,希望模糊 React 和 React Native 的界線帜篇,統(tǒng)一開發(fā)彻舰,這里的理念和 Flutter 很像伐割。

Flutter 暫時(shí)不支持熱更新:蛭丁!8粜摹0兹骸!<醚住4铡!

二须尚、Flutter 實(shí)戰(zhàn)

1崖堤、Dart 中有意思的一些東西

1.1、var 的語(yǔ)法糖和 dynamic

var 的語(yǔ)法糖是在賦值時(shí)才自推導(dǎo)出類型的 耐床,而 dynamic 是動(dòng)態(tài)聲明密幔,在運(yùn)行時(shí)檢測(cè),它們的使用有時(shí)候容易出現(xiàn)錯(cuò)誤撩轰。

如下圖所以說(shuō)胯甩,

  • var 初始化時(shí)被指定為 dynamic 類型的。
  • 然后賦值的時(shí)候初始化為 String 類型堪嫂,這時(shí)候進(jìn)行 ++ 操作就會(huì)出現(xiàn)運(yùn)行時(shí)報(bào)錯(cuò)偎箫,
  • 如下圖2如果在初始化指定類型的,那么編譯時(shí)就會(huì)告訴你錯(cuò)誤了皆串。
圖1
圖2

1.2淹办、各類操作符

如下圖所示,Dart 支持很多有意思的操作符恶复,如下圖:

  • 執(zhí)行的時(shí)候首先是判斷 AA 如果為空怜森,就返回 999
  • 之后如果 AA 為空谤牡,就為 AA 賦值 999副硅;
  • 之后對(duì) AA 進(jìn)行整除 999 ,輸出結(jié)果 10 翅萤。
image

1.3恐疲、支持操作符重載

如下圖所示,Dart 中是支持操作符重載的套么,這樣可以比較直觀我們的代碼邏輯流纹,并且簡(jiǎn)化代碼時(shí)的調(diào)用。

image15.png

1.4违诗、方法當(dāng)做參數(shù)傳遞

如下圖所示漱凝,在 Dart 中方法時(shí)可以作為參數(shù)傳遞的,這樣的形式可以讓我們更靈活的組織代碼的邏輯诸迟。

image

1.5茸炒、async await / async* yield

Dartasync await / async* yield 等語(yǔ)法糖愕乎,代表 Dart 中的 FutureStream 操作,它們對(duì)應(yīng) Dart 中的異步邏輯支持壁公。

sync* / yield 對(duì)應(yīng) Stream 的同步操作感论。

1.6、Mixins

Dart 中支持混入的模式紊册,如下圖所示比肄,混入時(shí)的基礎(chǔ)順序是從右到左依次執(zhí)行的,而且和 super 有關(guān)囊陡,同時(shí) Dart 還支持 mixin 關(guān)鍵字的定義芳绩。

image

Flutter 的啟動(dòng)類用的就是 mixins 方式

1.7、isolate

Dart 中單線程模式中增加了 isolate 提供跨線程的真異步操作撞反,而因?yàn)?Dart 中線程不會(huì)共享內(nèi)存妥色,所以也不存在死鎖,從而也導(dǎo)致了 isolate 之間數(shù)據(jù)只能通過(guò) port 的端口方式發(fā)送接口遏片,類似于 Scoket 的方式嘹害,同時(shí)提供了 compute 的封裝接口方便調(diào)用。

1.8 call

Dart 為了讓類可以像函數(shù)一樣調(diào)用吮便,默認(rèn)都可以實(shí)現(xiàn) call() 方法笔呀,同樣 typedef 定義的方法也是具備 call() 條件。

比如我定義了一個(gè) CallObject

class CallObject {

  List<Widget> footerButton = [];

  call(int i, double e) => "$i xxxx $e";
}

就可以通過(guò)以下執(zhí)行

CallObject callObject = CallObject();
print(callObject(11, 11.0));
print(callObject?.call(11, 11.0));

然后我定義了

typedef void ValueFunction(int i);

  ValueFunction vt = (int i){
    print("zzz $i");
  };

就可以通過(guò)直接執(zhí)行和判空?qǐng)?zhí)行處理

 vt(666);
 vt?.call(777);

2髓需、Flutter 中常見的

2.1凿可、ChangeNotifier

如下圖所示,ChangeNotifier 模式在 Flutter 中是十分常見的授账,比如 TextField 控件中,通過(guò) TextEditingController 可以快速設(shè)置值的顯示惨驶,這是為什么呢白热?

image18.png

如下圖所示,這是因?yàn)?TextEditingController 它是 ChangeNotifier 的子類粗卜,而 TextField 的內(nèi)部對(duì)其進(jìn)行了 addListener屋确,同時(shí)我們改變值的時(shí)候調(diào)用了notifyListener,觸發(fā)內(nèi)部 setState续扔。

image19.png

2.2攻臀、InheritedWidget

Flutter 中所有的狀態(tài)共享都是通過(guò)它實(shí)現(xiàn)的,如自帶的 Theme 纱昧,Localizations 刨啸,或者狀態(tài)管理的 scoope_modelflutter_redux 等等识脆,都是基于它實(shí)現(xiàn)的设联。

如下圖是 SliderTheme 的自定義實(shí)現(xiàn)邏輯善已,默認(rèn) Theme 中是包含了 SliderTheme,但是我們可以通過(guò)覆蓋一個(gè)新的 SliderTheme 嵌套去實(shí)現(xiàn)自定義离例,然后通過(guò) SliderTheme theme = SliderTheme(context); 獲取换团,其中而 context 的實(shí)現(xiàn)就是 Element

image20.png

ElementinheritFromWidgetOfExactType 方法實(shí)現(xiàn)里宫蛆,有一個(gè) Map<Type, InheritedElement> _inheritedWidgets 的對(duì)象艘包。

_inheritedWidgets 一般情況下是空的,只有當(dāng)父控件是 InheritedWidget 或者本身是 InheritedWidgets 時(shí)才會(huì)有被初始化耀盗,而當(dāng)父控件是 InheritedWidget 時(shí)想虎,這個(gè) Map 會(huì)被一級(jí)一級(jí)往下傳遞與合并 。
所以當(dāng)我們通過(guò) context 調(diào)用 inheritFromWidgetOfExactType 時(shí)袍冷,就可以往上查找到父控件的 Widget 磷醋。

2.3、StreamBuilder

StreamBuilder 一般用于通過(guò) Stream 異步構(gòu)建頁(yè)面的胡诗,如下圖所示邓线,通過(guò)點(diǎn)擊之后,綠色方框的文字會(huì)變成 addNewxxx煌恢,因?yàn)?Stream 進(jìn)行了 map 變化骇陈,同時(shí)一般實(shí)現(xiàn) bloc 模式的時(shí)候,經(jīng)常會(huì)用到它們瑰抵。

image21.png

類似的還有 FutureBuilder

2.4你雌、State 中的參數(shù)使用

一般 Widget 都是一幀的,而 State 實(shí)現(xiàn)了 Widget 的跨幀繪制二汛,一般定義的時(shí)候婿崭,我們可以如下圖一樣實(shí)現(xiàn),而如下圖尖頭所示肴颊,這時(shí)候我們點(diǎn)擊 setState 改變的時(shí)候氓栈,是不會(huì)出現(xiàn)效果的,為什么呢婿着?

image

其實(shí) State 對(duì)象的創(chuàng)建和更新時(shí)機(jī)導(dǎo)致的:

  • 1授瘦、createState 只在 StatefulElement 創(chuàng)建時(shí)才會(huì)被創(chuàng)建的。

  • 2竟宋、StatefulElement 的 createElement 一般只在 inflateWidget 調(diào)用提完。

  • 3、updateChild 執(zhí)行 inflateWidget 時(shí)丘侠, 如果 child 存在可以更新的話徒欣,不會(huì)執(zhí)行 inflateWidget。

image

3蜗字、四棵樹

Flutter 中主要有
Widget 帚称、Element 官研、RenderObjectLayer 四棵樹闯睹,它們的作用是:

  • Widget :就是我們平常寫的控件戏羽,Flutter 宇宙中萬(wàn)物皆 Widget ,它們都是不可變一幀楼吃,同時(shí)也是被人吐槽很多的嵌套模式始花,當(dāng)然換個(gè)角度,事實(shí)上你把他當(dāng)作 Widget 配置文件來(lái)寫或者就好理解了孩锡。

  • Element :它是 BuildContext 的實(shí)現(xiàn)類酷宵,Widget 實(shí)現(xiàn)跨幀保存的 state 就是存放在這里,同時(shí)它也充當(dāng)了 WidgetRenderObject 之間的橋梁躬窜。

  • RenderObject :它才是真正干活(layout浇垦、paint)等,同時(shí)它才是真實(shí)的 “dom” 荣挨。

  • Layer :一整塊的重繪區(qū)域(isRepaintBoundary)男韧,決定重繪的影響區(qū)域。

skia 在繪制的時(shí)候默垄,saveLayer 是比較消耗性能的此虑,比如透明合成、clipRRect 等等都會(huì)可能需要 saveLayer 的調(diào)用口锭, 而 saveLayer 會(huì)清空GPU繪制的緩存朦前,導(dǎo)致性能上的損耗,所以開發(fā)過(guò)程中如果掉幀嚴(yán)重鹃操,可以針對(duì)這一塊進(jìn)行優(yōu)化韭寸。

image

4、手勢(shì)

Flutter 在手勢(shì)中引入了競(jìng)技的概念, Down 事件在 Flutter 中尤為重要荆隘。

image
  • PointerDownEvent 是一切的起源恩伺,在 Down 事件中一般不會(huì)決出勝利者。

  • MOVEUP 的時(shí)候才競(jìng)爭(zhēng)得到響應(yīng)臭胜。

  • 以點(diǎn)擊為例子:Down 時(shí)添加進(jìn)去參與競(jìng)爭(zhēng),UP 的時(shí)候才決定誰(shuí)勝利癞尚,勝利條件是:

I耸三、UP 的時(shí)候如果只有一個(gè),那么就是它了浇揩。

II仪壮、UP 的時(shí)候如果有多個(gè),那么強(qiáng)制隊(duì)列里第一個(gè)直接勝利胳徽。

  • 這里包含了有趣的點(diǎn)就是积锅,都在 UP 的時(shí)候才響應(yīng)爽彤,那么 Down 事件怎么先傳遞出去了?

FLutter 在這里做了一個(gè) didExceedDeadline 機(jī)制 缚陷,事實(shí)上在上面的 addPointer 的時(shí)候适篙,會(huì)啟動(dòng)了一個(gè)定時(shí)器,默認(rèn) 100 ms箫爷,如果超過(guò)指定時(shí)間沒 UP 嚷节,那就先執(zhí)行這個(gè) didExceedDeadline 響應(yīng) Down 事件。

  • 那問(wèn)題又來(lái)了虎锚,如果這時(shí)候隊(duì)列里兩個(gè)呢?

它們的 onTapDown 都會(huì)被觸發(fā)硫痰,但是 onTap 只有一個(gè)獲得。

  • 如果有兩個(gè)滑動(dòng) ScrollView 嵌套呢窜护?

舉個(gè)簡(jiǎn)單的例子效斑,兩個(gè) SingleChildScrollView 的嵌套時(shí),在布局會(huì)經(jīng)歷:

performLayout -> applyContentDimensions -> applyNewDimensions -> context.setCanDrag(physics.shouldAcceptUserOffset(this));

只有 shouldAcceptUserOffsetture 時(shí)柱徙,才會(huì)添加 VerticalDragGestureRecognizer 去處理手勢(shì)缓屠。

而判斷條件主要是 return math.max(0.0, child.size.height - size.height); ,也就是如果 child Scroll 的 height 小于父控件 Scroll 的時(shí)候坐搔,就會(huì)出現(xiàn) child 不添加 VerticalDragGestureRecognizer 的情況藏研,這時(shí)候根本就沒有競(jìng)爭(zhēng)了。

5概行、動(dòng)畫

Flutter 中的動(dòng)畫是怎么執(zhí)行的呢蠢挡?

我們先看一段代碼,然后這段代碼執(zhí)行的效果如下圖2所示凳忙。

那既然 Widget 都是一幀业踏,那么動(dòng)畫肯定有 setState 的地方了。

首先這里有個(gè)地方可以看下涧卵,這時(shí)候 200 這個(gè)數(shù)值執(zhí)行后是會(huì)報(bào)錯(cuò)的勤家,因?yàn)榘卓騼?nèi)可見 Tween 中的 T 在這時(shí)候會(huì)出現(xiàn)既有 int 又有 double ,無(wú)法判斷的問(wèn)題柳恐,所以真實(shí)應(yīng)該是 200.0 伐脖。

image
image28.GIF

同時(shí)你發(fā)現(xiàn)沒有,代碼中 parentContainer 在 只有100的情況下乐设,它的 child 可以正常的畫 200讼庇,這是因?yàn)槲覀兊?paint 沒有跟著 RenerObjcet 的大小走, 所以一般情況下近尚,整個(gè)屏幕都是我們的畫版蠕啄,Canvas 繪制與父控件大小可以沒關(guān)系。

同時(shí)動(dòng)畫是通過(guò) vsync 同步信號(hào)去觸發(fā)的,就是我們 mixin 的 SingleTickerProviderStateMixin歼跟,它內(nèi)部的 Ticker 會(huì)通過(guò) SchedulerBindingscheduleFrameCallback 同步信號(hào)觸發(fā)重繪 和媳。

動(dòng)畫后的控件的點(diǎn)擊區(qū)域,和你的動(dòng)畫數(shù)據(jù)改變的是 paint 還是 layout 有關(guān) 哈街。

6留瞳、狀態(tài)管理

scope_modelflutter_redux叹卷、fish_redux 撼港、甚至還有有 dva_flutter 等等,可以看出狀態(tài)管理在 flutter 中和前端十分相近骤竹。

這里簡(jiǎn)單說(shuō)說(shuō) scope_model 帝牡,它只有一個(gè)文件,但是很巧妙蒙揣,它利用的就是 AnimationBuilder 的特性靶溜。

如下圖是使用代碼,在前面我們知道懒震,狀態(tài)管理使用的是 InheritedWidget 實(shí)現(xiàn)共享的罩息,而當(dāng)我們對(duì) Model 進(jìn)行數(shù)據(jù)改變時(shí),通過(guò)調(diào)用 notifyListeners 通知頁(yè)面更新了个扰。

image

這里的原理是什么呢瓷炮?

  • 其實(shí) scope_model 內(nèi)部利用了 AnimationBuilder ,而 Model 實(shí)現(xiàn)了 Listenable 接口递宅。

  • 當(dāng) Model 設(shè)置給了 AnimationBuilder 時(shí)娘香, AnimationBuilder 會(huì)執(zhí)行 addListener 添加監(jiān)聽,而監(jiān)聽方法里會(huì)執(zhí)行 setState办龄。

  • 所以我們改變 set 方法時(shí)調(diào)用 notifyListeners 就觸發(fā)了 setState 去更新了烘绽,這樣體現(xiàn)出了前面說(shuō)的 FLutter 常見的開發(fā)模式。

image

三俐填、混合開發(fā)

Android 的角度來(lái)說(shuō)安接,從方便調(diào)試和解耦集成上,我們一般會(huì)以 aar 的形式集成混合開發(fā)英融,這里就會(huì)涉及到 gradle 打包的一個(gè)概念盏檐。

1、如下代碼所示驶悟,在項(xiàng)目中進(jìn)行 gradle 腳本修改胡野,組件化開發(fā)模式,用 apk 開發(fā)撩银,用 aar 提供集成给涕,正常修改 gradle 代碼即可快速打包豺憔。

image

那如果 Flutter 的項(xiàng)目插件帶有本地代碼呢额获?

如果開發(fā)過(guò) React Native 的應(yīng)該知道够庙,在原生插件安裝時(shí)會(huì)需要執(zhí)行 react-native link ,而這時(shí)候會(huì)修改項(xiàng)目的gradle 和java代碼抄邀。

2耘眨、 和 React Native 很有侵入性相比, Flutter 就很巧妙了境肾。

如下圖所示剔难,安裝過(guò)的插件會(huì)出現(xiàn)在 .flutter_plugins 文件中,然后通過(guò)讀取文件奥喻,動(dòng)態(tài)在 setting.gradleflutter.gradle 中引入和依賴:

image
image
image

所以這時(shí)候我們可以參考打包偶宫,修改我們的gradle腳本,利用 fat-aar 插件將本地 projcet 也打包的 aar 里环鲤。

image

3纯趋、混合開發(fā)的最大痛點(diǎn)是什么?

肯定是堆棧管理!!! 所以項(xiàng)目開發(fā)了 flutter_boost 來(lái)解決這個(gè)問(wèn)題冷离。

  • 堆棧統(tǒng)一到了原生層吵冒。
  • 通過(guò)一個(gè)唯一 engine ,切換 Surface 渲染顯示西剥。
  • 每個(gè) Activity 就是一個(gè) Surface 痹栖,不渲染的頁(yè)面通過(guò)截圖緩存畫面。

flutter_boost 截止到我測(cè)試的時(shí)間 2019-05-16, 只支持 1.2之前的版本

image

四瞭空、PlatformView

混合開發(fā)除了集成到原生工程揪阿,也有將原生控件集成到 Flutter 渲染樹里里的需求。

首先我們看看沒有 PlatformView 之前是如何實(shí)現(xiàn) WebView 的匙铡,這樣會(huì)有什么問(wèn)題图甜?

如下圖所示,事實(shí)上 dart 中僅僅是用了一個(gè) SingleChildRenderObjectWidget 用于占位鳖眼,將大小傳遞給原生代碼黑毅,然后在原生代碼里顯示出來(lái)而已。

image

這樣的時(shí)候必定會(huì)代碼畫面堆棧問(wèn)題钦讳,因?yàn)檫@個(gè)顯示脫離了 Flutter 的渲染樹矿瘦,通過(guò)出現(xiàn)動(dòng)畫肯定會(huì)不一致。

4.1 AndroidView

AndroidView -> TextureLayer愿卒,利用Android 上的副屏顯示與虛擬內(nèi)存顯示原理缚去。

  • 共享內(nèi)存,實(shí)時(shí)截圖渲染技術(shù)琼开。

  • 存在問(wèn)題易结,耗費(fèi)內(nèi)存,頁(yè)面復(fù)雜時(shí)慢。

這部分因?yàn)橹耙郧傲倪^(guò)搞动,就不贅述了

三躏精、Flutter Web

RN因?yàn)槭窃丶栽趓eact 和react native 整合這件事上存在難度鹦肿。

flutter 作為一個(gè)UI 框架矗烛,與平臺(tái)無(wú)關(guān),在web上利用的是dart2js的能力箩溃。 比如Image

  • 因?yàn)?Flutter 是一套 UI 框架瞭吃,整體 UI 幾乎和平臺(tái)無(wú)關(guān),這和 React Native 有很大的區(qū)別涣旨。(我在開發(fā)過(guò)程中幾乎無(wú)知覺)
  • 在 flutter_web 中 UI 層面與渲染邏輯和 Flutter 幾乎沒有什么區(qū)別歪架,底層的一些區(qū)別如: flutter_web 中的 Canvas 是 EngineCanvas 抽象,內(nèi)部會(huì)借助 dart2js 的能力去生成標(biāo)簽霹陡。
  • React Native 平臺(tái)關(guān)聯(lián)性太強(qiáng)牡拇,而 Flutter 在多平臺(tái)上優(yōu)勢(shì)明顯。我們期待官方幫我們解決大部分的適配問(wèn)題穆律。
image38.png
image39.png
image40.GIF

Flutter 的平臺(tái)無(wú)關(guān)能力能帶來(lái)什么惠呼?

  • 1、某些功能頁(yè)面峦耘,可以一套代碼實(shí)現(xiàn)剔蹋,利用插件安裝引入,在web辅髓、移動(dòng)app泣崩、甚至 pc 上,都可以編譯出對(duì)應(yīng)平臺(tái)的高性能代碼洛口,而不會(huì)像 Weex 等一樣存在各種兼容問(wèn)題矫付。

  • 2、在應(yīng)用上可以快速實(shí)現(xiàn)“降級(jí)策略”第焰,比如某種情況下應(yīng)用產(chǎn)生奔潰了买优,可以替換為同等 UI 的 h5 顯示,而這些代碼只需要維護(hù)一份挺举。

image
image

資源推薦

GSYTech
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杀赢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子湘纵,更是在濱河造成了極大的恐慌脂崔,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梧喷,死亡現(xiàn)場(chǎng)離奇詭異砌左,居然都是意外死亡脖咐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門汇歹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)文搂,“玉大人,你說(shuō)我怎么就攤上這事秤朗。” “怎么了笔喉?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵取视,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我常挚,道長(zhǎng)作谭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任奄毡,我火速辦了婚禮折欠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吼过。我一直安慰自己锐秦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布盗忱。 她就那樣靜靜地躺著酱床,像睡著了一般。 火紅的嫁衣襯著肌膚如雪趟佃。 梳的紋絲不亂的頭發(fā)上扇谣,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音闲昭,去河邊找鬼罐寨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛序矩,可吹牛的內(nèi)容都是我干的鸯绿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼簸淀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼楞慈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起啃擦,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤囊蓝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后令蛉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聚霜,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狡恬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蝎宇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弟劲。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖姥芥,靈堂內(nèi)的尸體忽然破棺而出兔乞,到底是詐尸還是另有隱情,我是刑警寧澤凉唐,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布庸追,位于F島的核電站,受9級(jí)特大地震影響台囱,放射性物質(zhì)發(fā)生泄漏淡溯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一簿训、第九天 我趴在偏房一處隱蔽的房頂上張望咱娶。 院中可真熱鬧,春花似錦强品、人聲如沸膘侮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)喻喳。三九已至,卻和暖如春困曙,著一層夾襖步出監(jiān)牢的瞬間表伦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工慷丽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹦哼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓要糊,卻偏偏與公主長(zhǎng)得像纲熏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锄俄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容