Flutter教程(1)——快速預覽

林大元發表於2019-03-19

簡介

Flutter 是 Google 用以幫助開發者在 iOS 和 Android 兩個平臺開發高質量原生 UI 的移動 SDK。只需要維護一套程式碼就能在ios和Android中構建漂亮的App應用,並且效能不遜色於原生應用。這篇文章主要是通過走馬觀花的方式快速預覽Flutter。

整體框架

Flutter包括一個現代的響應式框架,一個2D渲染引擎、現成的widget和開發工具。這些元件可以幫助您快速地設計、構建、測試和除錯應用程式。

Flutter Widget

Flutter Widget一個現代響應式框架,主要從React中獲取的靈感,中心思想是用Widget構建UI。Weiget描述了他們的檢視。當widget的狀態傳送變化的時候,widget會重繪UI,Flutter會對比前後變化的不同,以確定底層渲染樹從一個狀態轉換到下一個狀態所需的最小更改,類似於React中虛擬DOM的diff演算法。總之Widget描述了Flutter的佈局和互動方式。

我們可以用簡單的"Hello,world"大體對比下Flutter和React的程式碼。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        'Hello, world!',
        textDirection: TextDirection.ltr,
      ),
    );
  }
}
複製程式碼

我們翻譯成React就像下面這樣

class MyApp extends Component {
  render() {
    return (
      <Center>
        <Text textDirection={TextDirection.ltr}>Hello, world!</Text>
      </Center>
    )
  }
}
複製程式碼

Flutter和React非常相似,只是把React的JSX變成了一個純物件,把Component變成StatelessWidget。個人認為JSX的描述方式比較直觀,第一是習慣問題,第二是用物件形式如果層層巢狀末尾都用“)”,很難辨認出對應的程式碼段是哪個控制元件,當然現在IDE都會在末尾自動註釋來解決這些問題。所以習慣因素是主導我覺得JSX比較好看的原因。

這裡一個知識點StatelessWidget是有無狀態元件,還有個有狀態元件StatefulWidget,可以通過setState()來改變狀態。熟悉React的同學是不是非常熟悉,這些內容後面會再講到。

總體上就是通過Widget來組合,像搭積木一樣描述介面。

Widget佈局描述

使用語言Dart

對的,Flutter既不是用JS/TS或者是Java這類的主流語言,而是用Dart。說道Dart其實很容易就會想到Typescript,他們其實都是altjs語言。Typescript目標是做到相容JS,是一個嚴格的超集。而Dart是完全推翻Javascript,採取替代的策略,重新制造一門語言。當然無論對於熟悉js或java的同學都很容易上手。網上有個網友寫的《為JavaScript開發人員準備的Dart參考教程》,可以快速的參考上手。

Flutter分層框架預覽

Flutter 整體架構主要分三層:Framework,Engine 與 Embedder。

Flutter分層框架圖

  1. Framework層,平常開發都在這層,Material和Cupertino是最最上層的設計框架,一個是Android的一個ios的,類似antD,只是一種UI設計框架,使用者自己選一個就好。Widgets上面提到的,這個是整個Flutter最重要的元件。然後就是渲染、動畫、手勢等。

  2. Engine是由C/C++寫的渲染引擎,包含SkiaDartText,這裡著重說下Skia渲染引擎,Skia是一個開源的二維圖形庫,提供各種常用的API,並可在多種軟硬體平臺上執行。谷歌Chrome瀏覽器、Chrome OS、安卓、火狐瀏覽器、火狐作業系統以及其它許多產品都使用它作為圖形引擎,也支援Windows 7+,macOS 10.10.5+,iOS8+,Android4.1+,Ubuntu14.04+ 等平臺。

  3. Embedder是一個嵌入層,即把Flutter嵌入到各個平臺上去,這裡做的主要工作包括渲染Surface設定,執行緒設定,以及外掛等。從這裡可以看出,Flutter的平臺相關層很低,平臺(android,iOS)只是提供一個畫布,剩餘的所有渲染相關的邏輯都在Flutter內部,這就使得它具有了很好的跨端一致性。但是這就導致一些問題,比如地圖這種外掛就需要額外的造輪子,而不能使用現有原生的外掛。但是我覺得跨端一致性才是款平臺最重要的理念,這方面生態上去必然會克服的。

對比React Native

Flutter直接競爭對手肯定是React Native,兩者都是非常優秀的跨平臺移動應用框架。

先看下React Native和Flutter近5年的Google搜尋熱度比較。

Google搜尋熱圖

可以看出React Native在2016年就開始穩健的上升,而Flutter是在2018年2月份的時候才開始有上升趨勢。現在Flutter依然是比React Native熱度低,但是非常接近了。雖然只是一個搜尋的熱度圖,但是可以側面的說明了,React Native因為比較早,成熟度比Flutter高,而Flutter到2018年才開始慢慢變熱門。

效能

React Native是通過Javascript在Chromium解釋執行然後呼叫原生元件渲染,Flutter通過Dart直接AOT編譯為原生程式碼,去控制Skia2d渲染引擎。所以從理論上來說,因為React Native多了一層Bridge解釋溝通,而Flutter是直接AOT編譯執行原生程式碼,並直接由Skia接管,速度是會優於React Native的。

如下圖(from What makes Flutter fast, Yuqian Li on D2),可以看到Flutter呼叫和Android原生呼叫是一模一樣的,直接由framework層呼叫到Skia,而ReactNative有個中間層去排程。

Flutter編譯原理

跨端一致性和保留原生

Flutter因為Skia,低層就是一個受控的畫布,Flutter可以讓你控制螢幕上的每一個畫素,可以讓你輕鬆生成動畫圖形、視訊、文字和控制元件,是真的可以達到跨端一致性。而React Native是用Javascript控制原生控制元件,壞處是要根據不同端差異性進行妥協,好處是保留了原生能力,就是原來原生的一套現在都可以用。跨端一致性和保留原生在一定程度上是一個矛盾體,就看個人如何衡量利弊了。但是我個人認為跨端一致性才是真的款平臺所需要的樣子。

穩定性和生態圈

React Native現在已經相對成熟了,目前許多坑比如拍照,地圖,視訊,通知......等等都得到了良好解決,但是Flutter還在這些填坑的路上,東西都有,但是能保證沒坑是不可能的。所以現階段除非新產品嚐鮮,不怕填坑,如果要穩定的輸出成熟的產品我還是推薦React Native的。

因為Flutter選擇Dart,生態圈遠比React Native小很多。畢竟React Native發展多年,又背靠Javascript、React、原生Native,這些是Flutter遠遠趕不上的。

開發上手

首先無論是Flutter還是React Native都需要Native開發相關的知識。但是Flutter畢竟要多學習一門新的語言Dart,雖然Dart很容易上手,但是好上手並不等於能彌補對這門語言的理解和坑,這些都需要經驗來填充的。所以上手難度還是比React Native高一些

總之我看重Flutter,不是因為他上層的Weiget框架和Dart語言,而是因為Flutter Engine底層渲染引擎,就算只看UI層,他抹平了平臺的差異,實現正的跨平臺一致性。但是如果把Weiget和Dart換成React和Typescript我會更加支援Flutter,這樣才是真的減少我們程式設計師的學習成本。畢竟同一套理念,換了一套標準去實現,是非常難受的一件事。當然Flutter是Google的,Typescript是微軟的,React是Facebook的,所以你們知道的,這隻能是我個人美好的烏托邦。

後續更新

相關文章