前言
本來這一篇應該介紹如何搭建Flutter開發環境的,但我想在瞭解Flutter前,不妨瞭解一下跨平臺技術的演進,這樣更有助於學習Flutter,也能認清Flutter的優勢和本質。這篇文章還有一個目的,就是希望大家是玩技術的人,而不是被技術玩的人,對於不同的技術要有自己的判斷。
1. 跨平臺技術的誕生
我是2010年開始從事的Android開發,當時會Android和iOS開發的很少,也不火,所有人都在“摸著河底過河”,專案更沒有第三方框架一說,大都是自己寫的,不像現在各種的框架滿天飛。隨著移動開發的發展,網際網路公司也是層出不窮,有些公司迫於競爭,想要更迅速的更省成本的進行開發,就不再滿足Android端一套程式碼,iOS端一套程式碼。與此同時,其他技術領域和各大公司也都覬覦著這份大蛋糕,紛紛推出相關的技術,這樣跨平臺技術應運而生,並且開始在公司中生根發芽。
Android和iOS生態太大了,我們可以把它們比作第一級生態,想要顛覆這兩個系統的曾經出現過,但都失敗了,因此建立次級生態是最穩妥的策略,Android平臺更加開放,因此次級生態的中心就是Android,次生態的形式多種多樣,比如在Android系統的基礎上魔改建立自己的生態,再或者推出各種跨平臺技術建立生態。跨平臺技術產生的框架實在太多了,很多還沒等我們去學去了解,它們就沒落了,成為了跨平臺技術的發展的一個過度產物。跨平臺技術的產物是不靠譜還是趨勢,我想讀完本篇文章你會有自己的理解。
跨平臺技術的分類沒有標準的答案,這裡把它們分類為5種,分別Web App、Hybrid App、語言編譯轉換、原生渲染、自繪UI。下面分別介紹它們。
2. Web App
Web App是指基於Web的應用,執行於網路和標準瀏覽器上,相當於一個網頁然後加一個App的殼。2014年HTML5的標準規範制定完成,在網路輿論上Web App大有取代Native App的氣勢,但Web App有以下缺點,使得它始終是“主角的心,配角的命” :
- 效能低,操作體驗不好
- 無法呼叫原生API,很多功能無法實現,
- 依賴於網路,網速慢時體驗很差,並且沒有離線功能,最佳化不好的話會消耗流量
- 只能做為一個臨時的入口,使用者留存率低
在Web App的基礎上,又出現了幾個進化者,這裡主要介紹PWA。
2.1 PWA
PWA(Progressive Web App)意為漸進式增強Web應用,它不是一門技術,而是一個概念,使用多種技術來增強 Web App的功能:
- 用Service Worker + HTTPS +Cache Api + indexedDB 等一系列web技術實現離線載入和快取
- 實現了推送和通知
- 可以直接新增到手機的桌面上
- 使用Service Worker可以進行後臺同步
總結起來,PWA的主要的能力就是離線、推送、桌面訪問,可以說PWA賦予Web App原生的體驗,但是PWA一直不溫不火的原因主要有以下幾點:
- 遊覽器對PWA技術支援還不夠全面, 不是每一款遊覽器都能100%的支援PWA
- 國內一些手機廠商對Android系統各種魔改,對PWA的相容性不好,甚至不支援PWA
- 平臺的競爭,iOS對PWA的支援力度遠遠低於Android,所以PWA在iOS上的體驗打了折扣。PWA面對類似的微信小程式和快應用的競爭中,並沒有優勢。
3. Hybrid App
除了採用原生和Web開發App,還可以採用HTML5+原生來進行混合開發,這就是Hybrid。
關於Hybrid的誕生有一個小故事,某個二線網際網路公司的App是以原生為主,HTML5開發打醬油,隨著應用越來越複雜,終於有一天發現原生有一個方法最大數限制,一些頁面需要內嵌HTML5的頁面,於是原生和HTML5團隊一起做了第一個Hybrid專案,這一套程式碼相容三端並且效率很高,因此Hybrid App就成了這個公司的主流,業界其他的公司也都紛紛效仿。
原生App的架構圖如下所示。
透過原生SDK提供的API,App可以與系統底層通訊,以建立 UI 元件或訪問系統服務。這些元件被渲染到手機螢幕,螢幕產生的相應的事件會被傳回給元件。因為每個平臺的系統元件是不同的,你需要為每個平臺開發單獨的 App,而Hybrid App不必這樣,Hybrid App的原生UI元件用來展示互動複雜和渲染要求高的介面,其他的可以交給HTML5來展示。
Hybrid App雖然開發效率高,可以跨平臺,但是Hybrid體驗比不上原生,對於需要快速試錯、快速佔領市場的團隊來說,Hybrid App是一個不錯的選擇,後期團隊穩定下來後,最好還是要做體驗更好的原生APP或者使用其他體驗更好的跨平臺技術。
Hybrid相關的技術有很多,比如PhoneGap、Cordova、Ionic、VasSonic等等,我們大概來了解一下。
3.1 Cordova
說到Cordova,不得不提到他的前身PhoneGap,PhoneGap面向Web開發人員,透過使用HTML、CSS和Javascript構建跨平臺App。2011年,Apache收購了Nitobi Software和它的PhoneGap產品,並對PhoneGap進行開源,PhoneGap 2.0版本時,產品更名為Apache Cordova。目前Cordova支援的平臺有Android、iOS、Windows、Mac OS X、Electron。
Cordova的體系結構圖如下所示。
Cordova同樣使用WebView來展示介面,外掛是Cordova中不可或缺的一部分,Apache Cordova維護了名為Core Plugins的外掛,這些核心外掛為App提供訪問裝置功能,如電池,相機,聯絡人等。除了核心外掛之外,還有一些第三方外掛可以使用,你也可以開發一個自己的外掛。
3.2 Ionic
Ionic Framework是一個開源UI工具包,最早的目標是使用HTML,CSS和JavaScript等Web技術開發移動應用程式。由於Web技術的這一基礎,Ionic可以在網路執行的任何地方執行,比如 iOS,Android,瀏覽器,Electron,PWA等等。
目前,Ionic Framework已與Angular正式整合,但對Vue和React的支援正在開發中。
3.3 VasSonic
VasSonic是由騰訊VAS團隊開發的輕量級高效能混合框架,旨在加速在Android和iOS平臺上執行的H5首屏。VasSonic不僅支援伺服器呈現的靜態或動態網站,而且還完美相容Web離線資源。VasSonic使用自定義的url連線而不是原始網路連線來請求索引html,因此它可以提前或並行請求資源以避免等待檢視初始化。在這種並行的情況下,VasSonic可以透過WebKit或Blink核心讀取和呈現部分資料,而無需花費太多時間等待資料流的結束。
3.4 微信小程式
微信小程式的主要開發語言是 JavaScript ,小程式的開發同普通的網頁開發相比有很大的相似性。
小程式的執行環境分成渲染層和邏輯層,這兩層分別由2個執行緒管理,渲染層的介面使用了WebView 進行渲染,邏輯層採用JsCore執行緒執行JS指令碼。這兩個執行緒的通訊會經由微信客戶端(Native)中的JSBridage做中轉。邏輯層傳送網路請求也經由Native轉發,小程式的通訊模型下圖所示。
其中 WXML 模板和 WXSS 樣式工作在渲染層,JS 指令碼工作在邏輯層。
微信小程式和PWA都是基於Web技術,原理的區別是小程式類似Hybrid架構,WebView渲染基本的網頁內容,對渲染效能要求較高的元件,透過原生元件來實現,比如相機、影片、地圖等等,另外傳統Web無法訪問的本地能力,需要透過JS SDK來實現,而PWA則是使用多種技術增強Web能力,以達到接近Native應用的體驗。
微信小程式本身和App就不是競爭關係,更多的是一個推廣渠道,它更像是一張海報,用於快速推廣倒流,而App則是要推廣的物件。微信小程式的缺點很明顯,體驗上無法跟App相提並論,功能依託並受限於微信,無法進行擴充。可以說微信小程式就是建立了次級生態,這個生態中微信說的算,其他對手的發展會受到限制。
4. 語言編譯轉換
語言編譯轉換指的是直接將某個語言編譯為一個平臺下的二進位制檔案。比較有名的是Xamarin框架,雖然它在 Android平臺是內嵌了Mono虛擬機器來實現的,但在 iOS平臺下是以AOT 的方式編譯為二進位制檔案的,所以把它歸到語言編譯轉換型別。
4.1 Xamarin
Xamarin始創於2011年,2016年被微軟正式收購。Xamarin是Mono專案的一個分支,基於.NET的跨平臺實現的一個開源專案。
與PhoneGap等框架不同的是,Xamarin可以在iOS和Android剛推出新的功能時,第一時間呼叫相應的API,而使用PhoneGap則需要等待PhoneGap封裝的新的功能後才可以呼叫相應的API。
Xamarin的Andriod實現原理如下圖所示。
C#程式碼寫的Andriod應用在執行的在Mono虛擬機器中,ART可以透過ACWs(Andriod Callable Wrappers)的方式執行到Mono中的C#程式碼。C#程式碼要是想呼叫系統功能或者Java的實現類庫,可以藉助MCW(Managed Callable Wrapper)的方式來實現。MCW是JNI的橋樑,可以使用託管程式碼呼叫Andriod程式碼。
5. 原生渲染
原生渲染在本篇文章中指的是由JavaScript開發並且由原生控制元件渲染,代表有React Native、Weex、快應用。
5.1 React Native
Facebook曾在移動端步履維艱,他們認為可以不借助任何原生開發手段來實現Facebook的移動應用,因此在早期選擇了HTML5,後來發現HTML5的效率始終無法和原生相比,因此在2015年釋出了React Native。
React Native是Facebook早先開源的 Web UI框架React在原生移動應用平臺的衍生產物,底層對Android和iOS平臺的原生程式碼進行封裝,透過使用JavaScript就可以編寫出原生程式碼。
Virtual DOM是DOM在記憶體中的一種輕量級表達方式,可以透過不同的渲染引擎生成不同平臺下的UI。React Native與原生框架透過Bridge進行通訊,如果使用Chrome瀏覽器進行除錯,那麼所有的JavaScript程式碼將執行在Chrome V8引擎中,透過WebSocket和原生程式碼進行通訊。
5.2 Weex
Weex 是阿里開源的一款跨平臺移動開發工具,它能夠完美兼顧效能與動態性,讓移動開發者透過簡捷的前端語法寫出原生級別的效能體驗,並支援iOS、Android、YunOS及Web等多端部署。目前 Vue.js 和 Rax 這兩個前端框架被廣泛應用於 Weex 頁面開發,因此Weex支援Vue語法和Rax語法,而React Native只支援JSX語法。
Weex首先將編寫的Weex原始碼,透過transformer轉換成JS Bundle。然後將JS Bundle部署在伺服器,當接收到終端(Android、Web端、iOS端)的JS Bundle請求時,將JS Bundle下發給終端。在終端中,由Weex的JS Framework 接收和執行JS Bundle程式碼,並且執行資料繫結、模板編譯等操作,然後輸出JSON 格式的 Virtual DOM,JS Framework傳送渲染指令給Native ,提供 callNative 和 callJS 介面,方便 JS Framework 和 Native 的通訊。
5.3 快應用
2018年3月份,由小米,OPPO,VIVO,華為等10家國內主流廠商成立了快應用聯盟。快應用介於移動網頁和原生應用之間,第三方應用以移動網頁的形式進行開發,最終得到原生渲染的效果體驗。快應用框架深度整合進各手機廠商的手機作業系統中,可以在作業系統層面形成使用者需求與應用服務的無縫連線,很多隻用在原生應用中才能使用的功能,在快應用中可以很方便的實現,享受原生應用體驗,同時不用擔心分發留存等問題,資源消耗也比較少。對於每臺手機裝置,應用可以從多個系統入口,引用使用者體驗產品。
與React Native和Weex相比主要有兩點不同:
- 快應用自身不支援Vue或React語法,它採用的是JavaScript開發。
- React Native和Weex的渲染引擎是整合到框架中的,每一個APP都需要打包一份,安裝包體積較大,快應用渲染引擎是整合到ROM中的,應用中無需打包,安裝包體積小。
和微信小程式很像,快應用本質上也是要建立次級生態,快應用的架構如下圖所示。
快應用實現劃分為編譯時、執行時兩個方面,UX頁面原始碼經過編譯時得到JS,然後經過執行時得到介面UI。每一個頁面由HTML+CSS+JS組成,編譯執行後得到記憶體中的DOM樹。多個頁面組成一個專案,編譯後得到rpk檔案,最終執行時以應用形態呈現。
快應用推出1年後仍然不溫不火,面對微信小程式,快應用在流量和入口等關鍵資料都無法與小程式匹敵,未來發展堪憂。
6. 自繪UI
自繪UI指的是透過在不同平臺實現一個統一介面的渲染引擎來繪製UI,而不依賴系統平臺的原生控制元件,這樣做可以保證不同平臺UI的一致性。不用像React Native一樣,隨著不同平臺系統版本的變化,開發者還需要處理不同平臺的差異,甚至有些特性只能在單個平臺上實現,這樣無法保證不同平臺UI的一致性。自繪UI框架的代表有Qt和Flutter。
6.1 Qt
Qt產生的時間很早,Qt 第一版於 1991 年由 Trolltech 釋出。後來在 2008 年,Nokia 斥資 1.5 億美元收購 TrollTech,將 Qt 應用於 Symbian 程式開發。2012 年 8 月 9 日,Nokia 將 Qt 以 400 萬歐元的價格出售給 Digia。2016年Qt Group Plc從Digia分拆出來,2014年Qt開始支援移動端的Android、iOS、Wp平臺。雖然Qt在PC領域發展良好,但在移動端表現不佳,很少有人提及或者用Qt去開發移動端。
6.2 Flutter
Flutter是谷歌的移動UI框架,可以快速在Android和iOS上構建高質量的原生使用者介面, 它的前身是谷歌試驗專案Sky。
Futter提出了一切皆Widget的概念,除了基本的文字、圖片、卡片、輸入框,佈局方式和動畫等也都是由Widget組成的。透過使用不同型別的Widget,就可以實現複雜度的介面。
Flutter框架採用了分層設計,此設計的目標是幫助開發者使用更少的程式碼完成更多工作。例如,Material層是由widgets層的普通widget組成的,而widgets層本身是透過來自rendering層的低階物件構建的。
目前在Flutter基礎上開發的框架已經開始出現,這也證明了業界普遍開始認可Flutter,並開始進行嘗試。
總結
跨平臺技術的分類沒有標準的答案,這裡也只是粗略的進行分類,並對每個分類的主流框架進行介紹,實際上還有很多框架沒有提到,它們不是沒落了,就是缺點明顯難以使用,再就是大公司的KPI產物。跨平臺技術的演進好比百家爭鳴,極大的促進了跨平臺技術的發展。在我看來,這些技術讓不同技術分支的程式設計師都可以參與到移動開發中,享受移動開發的樂趣,從這個角度來看這些跨平臺技術的優劣之分是很難去評判的。我更希望有一個框架能統一整個跨平臺技術,這個框架會是Flutter嗎?還是下一個未知的框架?你更看好哪個跨平臺技術呢?
本作品採用《CC 協議》,轉載必須註明作者和本文連結