H5 手機 App 開發入門:技術篇

阮一峰發表於2019-12-17

新人學習手機 App 開發,一開始總要選擇一條學習路徑。

如果你熟悉 Java 語言,可以學習安卓開發;如果熟悉指令碼語言(比如 Python 或 Ruby),可以學習 Swift 語言,進行 iOS 開發;如果像我一樣,比較熟悉 Web 網頁技術,那麼 H5 開發是最容易上手的。

這個系列教程的第一篇,已經介紹過了手機 App 的種類。所謂的 H5 頁面,其實就是混合 App 的前端,外面是一個原生的殼,裡面是 Web 網頁。本文緊接上一篇,介紹手機 App 開發的技術棧,尤其是跟 H5 開發相關的技術。

本文由國內最大的線上教育平臺之一"騰訊課堂"贊助。他們現在啟動了"騰訊課堂101計劃",推廣優質課程資源。希望學習和提高手機 App 開發技術的朋友,可以留意一下本文結尾的安卓課程資訊。

一、手機 App 的技術棧

手機 App 的技術棧可以分成三類。

(1)原生 App 技術棧 (native technology stack)

原生技術棧指的是,只能用於特定手機平臺的開發技術。比如,安卓平臺的 Java 技術棧,iOS 平臺的 Object-C 技術棧或 Swift 技術棧。

這種技術棧只能用在一個平臺,不能跨平臺。

(2)混合 App 技術棧 (hybrid technology stack)

混合技術棧指的是開發混合 App 的技術,也就是把 Web 網頁放到特定的容器中,然後再打包成各個平臺的原生 App。所以,混合技術棧其實是 Web 技術棧 + 容器技術棧,典型代表是 PhoneGap、Cordova、Ionic 等框架。

如果已經掌握了 Web 技術,這個技術棧就主要學習容器提供的 API Bridge,網頁透過它們去呼叫底層硬體的 API。

(3)跨平臺 App 技術棧 (cross-platform technology stack)

跨平臺技術棧指的是使用一種技術,同時支援多個手機平臺。它與混合技術棧的區別是,不使用 Web 技術,即它的頁面不是 HTML5 頁面,而是使用自己的語法寫的 UI 層,然後編譯成各平臺的原生 App。

這個技術棧就是純粹的容器技術棧,React Native、Xamarin、Flutter 都屬於這一類。學習時,除了學習容器的 API Bridge,還要學習容器提供的 UI 層,即怎麼寫頁面。

(4)小結

H5 開發主要用在混合技術棧。但是,跨平臺技術棧的某些容器也會用到(比如 React Native),因為它們的 UI 層借鑑了 Web 模型。

另外,混合技術棧和跨平臺技術棧的基礎,都是原生技術棧,因為最終都要編譯成原生App。所以,不管使用哪一種技術棧,多多少少要了解一些各平臺的原生技術。

下面就依次介紹上面三類技術棧,每個技術棧都會給出一個最簡單的例子:載入網頁。透過各種技術棧載入網頁的不同做法,幫助大家理解它們的特點,對 App 的技術實現有一個總體的認識。

二、WebView 控制元件

講解具體的技術棧之前,大家需要知道,不管什麼技術,最終在 App 裡面顯示網頁,一定需要一個網頁引擎,這樣才能解析網頁。

通常情況下,App 內部會使用 WebView 控制元件作為網頁引擎。這是系統自帶的控制元件,專門用來顯示網頁。應用程式的介面,只要放上 WebView,就好像內嵌了瀏覽器視窗,可以顯示網頁。

不同的 App 技術棧要顯示網頁,區別僅僅在於怎麼處理 WebView 這個原生控制元件。

  • 原生技術棧:需要開發者自己把 WebView 控制元件放到頁面上。
  • 混合技術棧:頁面本身就是網頁,預設在 WebView 中顯示。
  • 跨平臺技術棧:提供一個 WebView 的語法,編譯的時候將其換成原生的 WebView。

注意,不同系統的 WebView 控制元件名稱不一樣,安卓系統就叫 WebView,iOS 系統有較老的 UIWebView,也有較新的 WKWebView,作用都是一樣的,差異在於功能的強弱。

三、原生技術棧

原生技術棧分成 iOS 和安卓兩個平臺。

簡單說,iOS 的原生技術棧就是使用 Object-C 語言或 Swift 語言,在 Xcode 開發環境中程式設計。安卓的原生技術棧,則是使用 Java 語言或 Kotlin 語言,開發環境是 Android Studio。

下面就來看看,它們怎麼載入網頁。

3.1 Xcode

iOS 開發需要安裝 Xcode。它是一種整合開發環境(IDE),也是蘋果公司指定的 iOS 官方開發工具,所有蘋果手機的 App 都由它打包生成。

它可以在 Mac 電腦上透過應用商店免費安裝。注意,Xcode 只支援 Mac 系統,不支援其他系統。

安裝完成後,開啟新建一個專案,型別是單檢視 App,然後系統會詢問一些專案引數和儲存位置,這裡就不詳細說明了。

然後,就進入了開發環境。

左側的目錄樹裡面,找到ViewController.swifter檔案,它負責檢視邏輯。按照官方文件,填入下面的程式碼。

上面程式碼的意思是,啟動 App 載入檢視的時候(loadView()),新建一個 WebView 控制元件的例項。檢視載入成功後(viewDidLoad()),WebView 再去載入外部網頁(紅框部分)。

然後,就可以檢視程式碼執行結果。點選工具欄的執行按鈕,Xcode 就會彈出一個 iPhone 模擬器,裡面就是當前程式碼的執行結果。

如果一切正常,就可以讓 Xcode 對原始碼打包,生成 App 的二進位制安裝檔案。

3.2 Android Studio

安卓的官方開發工具是 Android Studio,可以去官網下載。

安裝完成後,開啟新建一個專案,型別是"Empty Activity"。

Android Studio 會詢問專案引數,包括專案名稱、開發語言(Java)等,然後就進入了開發環境。因為它是基於 Java IDE 修改的,懂 Java 的朋友應該對這個介面比較熟悉。

按照網上的這篇教程,接下來需要修改三個檔案,其中最主要的是把MainActivity.java檔案改成下面這樣。

上面紅框處的程式碼,就是在頁面上新增並設定 WebView 例項,指定生成檢視的時候(onCreate()),WebView 例項去載入外部網頁。

執行程式碼之前,Android Studio 要求必須連線真機,或安裝安卓模擬器。完成以後後,在工具欄上點選執行按鈕,就可以執行程式碼檢視效果了。

如果一切正常,就可以讓 Android Studio 打包,生成 App 的二進位制安裝檔案。

四、混合技術棧

上面的原生技術棧需要自己新建 WebView 例項,相比之下,混合技術棧就簡單多了。因為頁面就是網頁,所以容器已經設定好了 WebView,開發者直接寫頁面即可。

4.1 框架種類

混合技術棧的各種容器框架之中,歷史最悠久是 PhoneGap,誕生於2009年。後來在2011年被 Adobe 公司收購,改名為 Adobe PhoneGap。

Adobe 公司將 PhoneGap 的核心程式碼,後來都捐給了 Apache 基金會,作為一個全新的開源專案,名為 Apache Cordova

PhoneGap 和 Cordova 現在是兩個獨立發展的開源專案,但是彼此有密切的關係,可以簡單理解成 Cordova 是 PhoneGap 的核心,PhoneGap 是 Cordova 的發行版。

後來,其他人也開始基於 Cordova 封裝自己的框架,所以市場上有許多基於 Cordova 的開源框架,比較著名的有 IonicMonacaFramework7 等。

所有這些框架的共同點,都是使用 Web 技術(HTML5 + CSS + JavaScript)開發頁面,再由框架分別打包成 iOS 和安卓的 App 安裝包。它們的優點是開發簡單、週期短、成本低,缺點是功能和效能都很有限。

4.2 Ionic 例項

基於 Cordova 的框架,用法都大同小異,下面就以 Ionic 為例,演示如何載入外部網頁。

首先,根據官方文件,生成專案的腳手架。


$ npm install -g ionic@latest
$ ionic start myApp blank --type=react
$ cd myApp

接著開啟 src/pages/Home.tsx 檔案,插入 iframe 標籤即可。

上面程式碼中,由於頁面本身就是網頁,所以可以直接用iframe標籤插入外部網頁。

然後,在本機起一個 Web 服務,看看 Demo 的效果。


$ ionic serve

上面命令會自動開啟瀏覽器視窗,訪問本機的8100埠,在瀏覽器中顯示網頁效果。

如果一切正常,在命令列視窗按 Ctrl+c,退出服務。編譯成 App 安裝包的方法可以參考官方文件

五、跨平臺技術棧

上面的混合技術棧使用 HTML 語言編寫頁面,再用 WebView 控制元件載入頁面,所以只寫一次頁面,就能支援多個平臺。跨平臺技術棧也能做到多平臺支援,但是原理完全不同。

跨平臺技術棧的框架,都是使用自己的語法編寫頁面,不使用 Web 技術,編譯的時候再將其轉為原生控制元件,或者使用自己的底層控制元件,生成原生 App。這樣就完全解決了 Web 頁面效能不佳的問題。下面介紹三個這樣的框架。

  • React Native: 使用 JavaScipt 語言編寫頁面
  • Xamarin:使用 C# 語言編寫頁面
  • Flutter:使用 Dart 語言編寫頁面

5.1 React Native

(1)原理

2013年, Facebook 公司釋出了 React 框架。這個框架是為網頁開發設計的,核心思想是在網頁之上,建立一個 UI 的抽象層,所有資料操作都在這個抽象層完成(即在記憶體裡面完成),然後再渲染成網頁的 DOM 結構,這樣就提升了效能。

很快,工程師們就意識到了,UI 抽象層本質上是一種資料結構,與底層裝置無關,不僅可以渲染成網頁,也可以渲染成手機的原生頁面。這樣的話,只要寫一次 React 頁面,就能分別編譯成 iOS 和安卓的原生 App。這就是 React Native 專案的由來。

注意,React Native 雖然也使用 JavaScript 語言,並且寫法看上去像 Web 頁面,但其實所有控制元件都是自己定義的,編譯時再一一翻譯為對應的原生控制元件。舉例來說,React Native 的文字渲染控制元件是<Text>,翻譯成 iOS 控制元件為UIView,翻譯成安卓控制元件為TextView。這種做即保證了效能,又做到了跨平臺支援,所以一誕生就引起開發者的關注,成了熱門技術。

還有一個 NativeScript 框架,跟 React Native 很像,也是使用 JavaScript 語言,然後編譯成原生控制元件。不過,它的開發模型是基於 Angular.js,而不是 React。

(2)例項

下面就是 React Native 載入外部網頁的例項。為了方便使用,官方團隊提供了一個封裝好的工具集,叫做 Expo。第一步,在手機安裝 Expo 的 App 客戶端(App StoreGoogle Play)。

然後,在命令列安裝腳手架工具expo-cli,新建一個示意專案。


$ npm install -g expo-cli
$ expo init rnDemo

新建專案時,會要求你選擇專案模板,可以選minimum模板。然後,還會要求你填寫專案描述displayName,這個可以隨便寫。

然後,安裝 React Native 自己的 WebView 控制元件。


$ cd rnDemo
$ npm install --save react-native-webview

接著,開啟主頁面的指令碼檔案App.js,將其改成下面的程式碼。

上面程式碼中,React Native 自身的WebView控制元件,編譯時會分別轉為 iOS 和安卓的原生 WebView 控制元件。

接下來,預覽頁面效果。可以先把它編譯成 Web 版,在瀏覽器預覽,這樣比較快,立刻就能看到效果。


$ npm run web

執行上面的命令,命令列會出現一個二維碼。

這時可以開啟手機端的 Expo 客戶端,掃描這個二維碼,就會顯示 App 的頁面。注意,計算機和手機必須在同一個區域網。

(3)React Native 的問題

React Native 的想法雖然很美好,但是實際開發中出現了各種各樣的問題。

最主要的一個問題是, UI 抽象層翻譯出來的 iOS 和安卓原生頁面,做不到完全一致,尤其是複雜頁面,樣式或功能存在差異。編譯出來兩個平臺的原生 App 往往是一個正常,另一個會出現各種奇怪的小毛病。React Native 的底層還是沒有做到無縫適配,它至今沒有釋出 1.0 版(2019年底是 0.61 版),這多多少少也說明了一些問題。

如果你想用 React Native 做到 iOS 和安卓體驗一致,並且充分發揮原生控制元件的功能,就需要同時熟悉 React Native、iOS、安卓三個平臺,這對開發者的要求實在太高了。Airbnb 公司在使用 React Native 兩年後,宣佈放棄,改用原生技術棧。他們寫了一篇很長的文章,解釋為什麼這麼做,React Native 到底有什麼問題,大家可以參考那篇文章。

5.2 Xamarin

Xamarin 是微軟公司的跨平臺 App 開發框架,原理跟 React Native 很相似,只不過它的語言是 C#。

它的使用需要 Visual Studio,這裡就不舉例了。根據官方文件,WebView 的用法如下。

上面程式碼中,首先新建了一個 WebView 控制元件的例項,然後把這個例項放到佈局上,跟原生 App 的語法很像。

5.3 Flutter

Flutter 是谷歌公司最新的跨平臺開發框架。它為了解決 React Native 的平臺差異問題,採用了一個完全不同的方案。

它自己實現了一套控制元件。打包的時候,會把這套控制元件打包進每一個 App,因此不存在呼叫原生控制元件的問題。不管什麼平臺,都呼叫內嵌的自己那套控制元件,就能做到 iOS 和安卓體驗完全一致。

Flutter 歷史還不長,應用還不廣泛,API 也沒穩定下來。但是很值得關注。

載入外部網頁的例項,可以參考 Flutter 官方團隊的這篇文章。核心程式碼如下:

上面程式碼使用的是 Dart 語言。它是 Flutter 的官方語言,接近 JavaScript 語法,但是多了靜態型別支援。

六、總結

透過上面的介紹,希望大家已經瞭解了各種技術棧的特點。

(1)原生技術棧的技能和體驗最好,對於複雜的大型 App,如果條件允許,應該採用這種方式開發。

(2)混合技術棧的成本低,靈活性好,對效能要求不高的簡單 App,尤其是純展示性的頁面,可以採用這種方式開發。

(3)跨平臺技術棧適用於,存在外部或內部條件的限制,只有一個團隊開發跨平臺 App 的情況。

(正文完)

安卓開發高階 UI 課程

手機 App 的 UI(使用者介面),往往是 App 成功的關鍵因素:產品的外觀是否漂亮,點選和滑動是否流暢,意圖是否清晰,都會影響到使用者的留存率。一個好的 UI 不僅體現了產品經理和開發者的素質,還可以有效降低拉新成本。

一般的開發者接到產品的 UI 設計方案之後,可能就會去網上找類似的效果,看看有沒有開原始碼。但是,優秀的開發者會努力思考,如何透過完全自定義來實現這個效果,做到功能和效能的最佳狀態。

這就要求開發者具有實現高階 UI 的開發能力,理解安卓 UI 的底層實現原理,比如自定義 View 的渲染流程(onMeasure -> onLayout -> onDraw),以及互動設計(touch事件)。

怎樣才能高效地學習安卓高階 UI 開發,早日進階成為高階安卓工程師呢?這裡介紹享學課堂的一門課程 《高階安卓 UI ----自定義 ViewGroup 與 UI 效能最佳化》,它帶大家一行一行程式碼去實現一個京東自定義ViewGroup,研究系統的FrameLayoutViewPager的原始碼,最後透過閱讀原始碼,分析ViewPager設計過程中的顯示問題和效能問題。下圖是課程介紹(點選看大圖)。

這個課程是直播課程,線上實時答疑,特別邀請了 Alvin 老師(前三星/小米高階研發經理)主講,只需要0.1元就能參與 。聽課之後覺得滿意,還可以學習其他 Android 高階進階的實戰課程。

現在就可以微信掃描上面圖片的二維碼(手機端長按兩次),進群報名。還可以免費領取 15GB 的安卓進階必備學習資料(文字材料 + 影片教程)。

(完)

相關文章