# 1. 原生開發(fā)原生應用程序是指某一個移動平臺(比如iOS或安卓)所特有的應用,使用相應平臺支持的開發(fā)工具和語言,,并直接調(diào)用系統(tǒng)提供的SDK API,。比如Android原生應用就是指使用Java或Kotlin語言直接調(diào)用Android SDK開發(fā)的應用程序;而iOS原生應用就是指通過Objective-C或Swift語言直接調(diào)用iOS SDK開發(fā)的應用程序,。原生開發(fā)有以下主要優(yōu)勢:
主要缺點:
在移動互聯(lián)網(wǎng)發(fā)展初期,,業(yè)務場景并不復雜,,原生開發(fā)還可以應對產(chǎn)品需求迭代。 但近幾年,,隨著物聯(lián)網(wǎng)時代到來,、移動互聯(lián)網(wǎng)高歌猛進,日新月異,,在很多業(yè)務場景中,,傳統(tǒng)的純原生開發(fā)已經(jīng)不能滿足日益增長的業(yè)務需求。主要表現(xiàn)在:
總結一下,純原生開發(fā)主要面臨動態(tài)化和開發(fā)成本兩個問題,,而針對這兩個問題,誕生了一些跨平臺的動態(tài)化框架,。 # 2. 跨平臺技術簡介針對原生開發(fā)面臨的問題,,業(yè)界一直都在努力尋找好的解決方案,而時至今日,,已經(jīng)有很多跨平臺框架(注意,,本書中所指的“跨平臺”若無特殊說明,即特指 Android 和 iOS 兩個平臺),,根據(jù)其原理,主要分為三類:
在接下來的章節(jié)中我們逐個來看看這三類框架的原理及優(yōu)缺點,。 # 1.1.2 Hybrid技術簡介# 1. H5 + 原生這類框架主要原理就是將 App 中需要動態(tài)變動的內(nèi)容通過HTML5(簡稱 H5)來實現(xiàn),通過原生的網(wǎng)頁加載控件WebView (Android)或 WKWebView(iOS)來加載(以后若無特殊說明,,我們用WebView來統(tǒng)一指代 Android 和 iOS 中的網(wǎng)頁加載控件),。這種方案中,H5 部分是可以隨時改變而不用發(fā)版,,動態(tài)化需求能滿足,;同時,由于 H5 代碼只需要一次開發(fā),,就能同時在 Android 和 iOS 兩個平臺運行,,這也可以減小開發(fā)成本,也就是說,,H5 部分功能越多,,開發(fā)成本就越小。我們稱這種 H5 + 原生 的開發(fā)模式為混合開發(fā) ,,采用混合模式開發(fā)的App我們稱之為混合應用或 HTMLybrid App ,,如果一個應用的大多數(shù)功能都是 H5 實現(xiàn)的話,,我們稱其為 Web App 。 目前混合開發(fā)框架的典型代表有:Cordova,、Ionic ,。大多數(shù) App 中都會有一些功能是 H5 開發(fā)的,,至少目前為止,,HTMLybrid App 仍然是最通用且最成熟的跨端解決方案。 在此,,我們需要提一下小程序,目前國內(nèi)各家公司小程序應用層的開發(fā)技術棧是 Web 技術棧,,而底層渲染方式基本都是 WebView 和原生相結合的方式,。 # 2. 混合開發(fā)技術點如之前所述,,原生開發(fā)可以訪問平臺所有功能,,而混合開發(fā)中,H5代碼是運行在 WebView 中,,而 WebView 實質(zhì)上就是一個瀏覽器內(nèi)核,,其 JavaScript 依然運行在一個權限受限的沙箱中,所以對于大多數(shù)系統(tǒng)能力都沒有訪問權限,,如無法訪問文件系統(tǒng),、不能使用藍牙等。所以,,對于 H5 不能實現(xiàn)的功能,,就需要原生去做了。 混合框架一般都會在原生代碼中預先實現(xiàn)一些訪問系統(tǒng)能力的 API ,, 然后暴露給 WebView 以供 JavaScript 調(diào)用,。這樣一來,WebView 中 JavaScript 與原生 API 之間就需要一個通信的橋梁,,主要負責 JavaScript 與原生之間傳遞調(diào)用消息,,而消息的傳遞必須遵守一個標準的協(xié)議,它規(guī)定了消息的格式與含義,我們把依賴于 WebView 的用于在 JavaScript 與原生之間通信并實現(xiàn)了某種消息傳輸協(xié)議的工具稱之為 WebView JavaScript Bridge , 簡稱 JsBridge,,它也是混合開發(fā)框架的核心。 # 1) 示例:JavaScript調(diào)用原生API獲取手機型號下面我們以 Android 為例,,實現(xiàn)一個獲取手機型號的原生 API 供 JavaScript 調(diào)用,。在這個示例中將展示 JavaScript 調(diào)用原生 API 的流程,讀者可以直觀的感受一下調(diào)用流程,。我們選用筆者在Github上開源的 dsBridge作為 JsBridge 來進行通信,。dsBridge 是筆者實現(xiàn)的一個跨平臺的 JsBridge 庫,此示例中只使用其同步調(diào)用功能,。
將原生API通過WebView注冊到JsBridge中 import wendu.dsbridge.DWebView...//DWebView繼承自WebView,,由dsBridge提供 DWebView dwebView = (DWebView) findViewById(R.id.dwebview);//注冊原生API到JsBridgedwebView.addJavascriptObject(new JsAPI(), null); 在JavaScript中調(diào)用原生API var dsBridge = require("dsbridge")//直接調(diào)用原生API `getPhoneModel`var model = dsBridge.call("getPhoneModel");//打印機型console.log(model); 上面示例演示了 JavaScript 調(diào)用原生 API 的過程,同樣的,,一般來說優(yōu)秀的 JsBridge 也支持原生調(diào)用 JavaScript ,,dsBridge 也是支持的,如果您感興趣,,可以去 Github dsBridge 項目主頁查看,。 現(xiàn)在,我們回頭來看一下,,混合應用無非就是在第一步中預先實現(xiàn)一系列 API 供 JavaScript 調(diào)用,,讓 JavaScript 有訪問系統(tǒng)功能的能力,看到這里,,我相信你也可以自己實現(xiàn)一個混合開發(fā)框架了,。 # 3. 小結混合應用的優(yōu)點是動態(tài)內(nèi)容是 H5,Web 技術棧,,社區(qū)及資源豐富,,缺點是性能體驗不佳,對于復雜用戶界面或動畫,,WebView 有時會不堪重任。 # 1.1.3 React Native,、Weex本篇主要介紹一下 JavaScript開發(fā) + 原生渲染 的跨平臺框架原理。 React Native (簡稱 RN )是 Facebook 于 2015 年 4 月開源的跨平臺移動應用開發(fā)框架,,是 Facebook 早先開源的 Web 框架 React 在原生移動應用平臺的衍生產(chǎn)物,,目前支持 iOS 和 Android 兩個平臺。RN 使用JSX 語言(擴展后的 JavaScript,,主要是可以在 JavaScript 中寫 HTML標簽)和 CSS 來開發(fā)移動應用,。因此,熟悉 Web 前端開發(fā)的技術人員只需很少的學習就可以進入移動應用開發(fā)領域。 由于 RN 和 React 原理相通,,并且 Flutter在應用層也是受 React 啟發(fā),,很多思想也都是相通的,因此,,我們有必要深入了解一下React原理,。 React 是一個響應式的 Web 框架,我們先了解一下兩個重要的概念:DOM 樹與響應式編程,。 # 1. DOM樹與控件樹文檔對象模型(Document Object Model,,簡稱DOM),是 W3C 組織推薦的處理可擴展標志語言的標準編程接口,,一種獨立于平臺和語言的方式訪問和修改一個文檔的內(nèi)容和結構,。換句話說,這是表示和處理一個 HTML 或XML 文檔的標準接口,。簡單來說,,DOM 就是文檔樹,與用戶界面控件樹對應,,在前端開發(fā)中通常指 HTML 對應的渲染樹,,但廣義的 DOM 也可以指 Android 中的 XML 布局文件對應的控件樹,而術語DOM操作就是指直接來操作渲染樹(或控件樹),, 因此,,可以看到其實 DOM 樹和控件樹是等價的概念,只不過前者常用于 Web 開發(fā)中,,而后者常用于原生開發(fā)中,。 # 2. 響應式編程React 中提出一個重要思想:狀態(tài)改變則UI隨之自動改變。而 React 框架本身就是響應用戶狀態(tài)改變的事件而執(zhí)行重新構建用戶界面的工作,,這就是典型的 響應式 編程范式,,下面我們總結一下 React 中響應式原理:
值得注意的是,,在第二步中,,狀態(tài)變化后 React 框架并不會立即去計算并渲染 DOM 樹的變化部分,相反,,React會在 DOM 樹的基礎上建立一個抽象層,,即虛擬DOM樹,對數(shù)據(jù)和狀態(tài)所做的任何改動,,都會被自動且高效的同步到虛擬 DOM ,,最后再批量同步到真實 DOM 中,而不是每次改變都去操作一下DOM,。 為什么不能每次改變都直接去操作 DOM 樹,?這是因為在瀏覽器中每一次 DOM 操作都有可能引起瀏覽器的重繪或回流(重新排版布局,確定 DOM 節(jié)點的大小和位置):
而瀏覽器的重繪和回流都是比較昂貴的操作,如果每一次改變都直接對 DOM 進行操作,,這會帶來性能問題,,而批量操作只會觸發(fā)一次 DOM 更新,會有更高的性能,。
# 3. React Native上文已經(jīng)提到 React Native 是 React 在原生移動應用平臺的衍生產(chǎn)物,,那兩者主要的區(qū)別是什么呢,?其實,主要的區(qū)別在于虛擬 DOM 映射的對象是什么,。React中虛擬 DOM 最終會映射為瀏覽器 DOM 樹,,而 RN 中虛擬 DOM會通過 JavaScriptCore 映射為原生控件。 JavaScriptCore 是一個JavaScript解釋器,,它在React Native中主要有兩個作用:
而 RN 中將虛擬 DOM 映射為原生控件的過程主要分兩步:
至此,,React Native 便實現(xiàn)了跨平臺。 相對于混合應用,,由于React Native是 原生控件渲染,,所以性能會比混合應用中 H5 好一些,同時 React Native 提供了很多原生組件對應的 Web 組件,,大多數(shù)情況下開發(fā)者只需要使用 Web 技術棧 就能開發(fā)出 App,。我們可以發(fā)現(xiàn),這樣也就做到了維護一份代碼,,便可以跨平臺了,。 # 4. WeexWeex 是阿里巴巴于 2016 年發(fā)布的跨平臺移動端開發(fā)框架,思想及原理和 React Native 類似,,底層都是通過原生渲染的,,不同是應用層開發(fā)語法 (即 DSL,Domain Specific Language):Weex 支持 Vue 語法和 Rax 語法,,Rax 的 DSL(Domain Specific Language) 語法是基于 React JSX 語法而創(chuàng)造,,而 RN 的 DSL 是基于 React 的,不支持 Vue,。 # 5. 小結JavaScript 開發(fā) + 原生渲染 的方式主要優(yōu)點如下:
不足:
# 1.1.4 Qt Mobile# 1. 自繪UI + 原生我們看看最后一種跨平臺技術:自繪UI + 原生。這種技術的思路是:通過在不同平臺實現(xiàn)一個統(tǒng)一接口的渲染引擎來繪制UI,,而不依賴系統(tǒng)原生控件,,所以可以做到不同平臺UI的一致性。 注意,,自繪引擎解決的是 UI 的跨平臺問題,,如果涉及其他系統(tǒng)能力調(diào)用,依然要涉及原生開發(fā),。這種平臺技術的優(yōu)點如下:
不足:
也許你已經(jīng)猜到 Flutter 就屬于這一類跨平臺技術,,沒錯,,F(xiàn)lutter 正是實現(xiàn)一套自繪引擎,并擁有一套自己的 UI 布局系統(tǒng),,且同時在開發(fā)效率上有了很大突破,。不過,自繪制引擎的思路并不是什么新概念,,F(xiàn)lutter并不是第一個嘗試這么做的,,在它之前有一個典型的代表,即大名鼎鼎的Qt,。 # 2. Qt 簡介Qt 是一個1991年由 Qt Company 開發(fā)的跨平臺 C++ 圖形用戶界面應用程序開發(fā)框架,。2008年,Qt Company 科技被諾基亞公司收購,,Qt 也因此成為諾基亞旗下的編程語言工具,。2012年,Qt 被 Digia 收購,。2014年4月,,跨平臺集成開發(fā)環(huán)境 Qt Creator 3.1.0 正式發(fā)布,實現(xiàn)了對于 iOS 的完全支持,,新增 WinRT,、Beautifier 等插件,廢棄了無 Python 接口的 GDB 調(diào)試支持,,集成了基于 Clang 的 C/C++ 代碼模塊,,并對 Android 支持做出了調(diào)整,至此實現(xiàn)了全面支持 iOS,、Android,、WP,它提供給應用程序開發(fā)者構建圖形用戶界面所需的所有功能,。 但是,,Qt 雖然在 PC 端獲得了巨大成功,,備受社區(qū)追捧,然而其在移動端卻表現(xiàn)不佳,,在近幾年,,雖然偶爾能聽到 Qt 的聲音,但一直很弱,,無論 Qt 本身技術如何,、設計思想如何,但事實上終究是敗了,,究其原因,,筆者認為主要有四: 第一:Qt 移動開發(fā)社區(qū)太小,學習資料不足,,生態(tài)不好,。 第二:官方推廣不利,支持不夠,。 第三:移動端發(fā)力較晚,,市場已被其他動態(tài)化框架占領( Hybrid 和 RN )。 第四:在移動開發(fā)中,,C++ 開發(fā)和Web開發(fā)棧相比有著先天的劣勢,,直接結果就是 Qt 開發(fā)效率太低。 基于此四點,,盡管 Qt 是移動端開發(fā)跨平臺自繪引擎的先驅(qū),,但卻成為了烈士。 # 1.1.5 Flutter出世“千呼萬喚始出來”,,鋪墊這么久,,現(xiàn)在終于等到本書的主角出場了! Flutter 是 Google 發(fā)布的一個用于創(chuàng)建跨平臺,、高性能移動應用的框架,。Flutter 和 Qt mobile 一樣,都沒有使用原生控件,,相反都實現(xiàn)了一個自繪引擎,,使用自身的布局、繪制系統(tǒng),。那么,,我們會擔心,Qt mobile 面對的問題Flutter是否也一樣,,F(xiàn)lutter會不會步入Qt mobile后塵,,成為另一個烈士?要回到這個問題,我們先來看看Flutter誕生過程:從 2017 年 Google I/O 大會上,,Google 首次發(fā)布 Flutter 到 2021年8月底,,已經(jīng)有 127K 的 Star,Star 數(shù)量 Github 上排名前 20 ,。經(jīng)歷了4年多的時間,,F(xiàn)lutter 生態(tài)系統(tǒng)得以快速增長,國內(nèi)外有非常多基于 Flutter 的成功案例,,國內(nèi)的互聯(lián)網(wǎng)公司基本都有專門的 Flutter 團隊,。總之,,歷時 4 年,F(xiàn)lutter 發(fā)展飛快,,已在業(yè)界得到了廣泛的關注和認可,,在開發(fā)者中受到了熱烈的歡迎,成為了移動跨端開發(fā)中最受歡迎的框架之一,。 現(xiàn)在,,我們來和 Qt mobile做一個對比:
基于以上三點,,相信讀者和筆者一樣,,已經(jīng)迫不及待的想要去了解一下 Flutter 了。到現(xiàn)在為止,,我們已經(jīng)對移動端開發(fā)技術有了一個全面的了解,,接下來我們便要進入本書的主題,你準備好了嗎,! # 1.1.6 小結本章主要介紹了目前移動開發(fā)中三種跨平臺技術,,現(xiàn)在我們從框架角度對比一下它們,如表1-1所示:
上表中開發(fā)語言主要指應用層的開發(fā)語言,,而開發(fā)效率,,是指整個開發(fā)周期的效率,包括編碼時間,、調(diào)試時間,、以及排錯、處理兼容性問題時間,。動態(tài)化主要指是否支持動態(tài)下發(fā)代碼和是否支持熱更新,。值得注意的是 Flutter 的Release 包默認是使用 Dart AOT 模式編譯的,所以不支持動態(tài)化,,但 Dart 還有 JIT 或 snapshot 運行方式,,這些模式都是支持動態(tài)化的。 |
|
來自: hewii > 《App Frameworks》