Hybrid App 跨平臺熱更新方案實踐 附帶原始碼

free46000發表於2017-06-21

前言

移動開發的跨平臺與快速釋出一直是開發者的追求,也是技術的一個發展趨勢,現在各大廠開始有了自己的大前端團隊,所以我們也開始了自己的探索,目前來說主要有兩種思路:

  • Hybrid App 代表:Cordova
    通過Webview載入Web頁面,在NativeWeb頁面之間建立雙向通訊
  • H5程式碼Native化 代表:ReactNative,Weex
    使用各平臺Api,把H5程式碼編譯成二進位制程式碼直接執行

其實關於這兩種思路對比,網上有很多大牛分析的很全面了,總結來說各有利弊很難完美,本篇文章我們主要講一下Hybrid App實踐,採用前後端分離以及單頁應用技術開發Web頁面,使用WebView載入Web頁面,並通過JS通訊提供一些Native層的支援,通過介面獲取差異化頁面資原始檔,在本地整合更新,還可以達到熱更新的需求。在我看來此方案更適用於需要快速釋出、多端相容、對效能要求稍低的業務,正好符合我們的需求。

原始碼

這裡我整理了Android端會用到程式碼,包含JS通訊,檔案處理工具類,閃屏輔助類和WebView的封裝。
Github地址:github.com/free46000/H…,請大家多多關注,由於原始碼並沒有完善,所以暫時沒有釋出到Maven倉庫

方案詳解

既然確定了方向,那麼就應該確定具體的方案了,通過自己的經驗和網上資料整理,畫了時序圖:

Hybrid App 跨平臺熱更新方案實踐 附帶原始碼
image

按照圖上的時序,接下來說一下每一步中的實踐,以及碰到的坑。下面講解

初次安裝

  • 打包
    在打包程式時這一步主要是把Html相關資原始檔壓縮後放在assets資料夾下即可
  • 安裝
    使用者安裝完應用程式開啟後,檢測是否為初次使用,如果是則通過程式直接解壓包內資源到手機儲存上即可,不侷限於SD卡。

展示頁面

  • 閃屏頁展示
    由於上面的解壓資源,還有Webview初始化、JS的載入執行、html的渲染都是耗時操作,並且都是發生在Html展示之前,所以我們選擇把閃屏頁用Native原生程式碼來編寫,採用覆蓋WebView所在頁面的方案,這樣在閃屏頁隱藏的時候,使用者就可以看到業務介面,提升使用者體驗。
    注:另外提供Android兩種閃屏優化的小技巧,使用透明主題或者設定主題背景圖片

  • 載入本地Html頁面
    直接使用WebView#loadUrl()載入本地資原始檔即可。由於WebView載入不同頁面會出現閃屏的問題,所以我們採用Vue + Vue Router構建單頁應用。
    這裡Vue Router會有一個小坑,提醒大家注意一下:Vue Router預設採用hash模式,會有一個醜陋的#符號,作為一個有追求的程式設計師怎麼能允許這種很醜的hash,一種更優雅的方式使用HTML5 History模式,但是不幸的是,載入本地資原始檔的方式並不能正常解析HTML5 History模式的url,所以只能採用hash模式。

  • 資料請求
    為了節省使用者的流量和時間,需要把Html資原始檔儲存在本地,這樣資料的請求必須在客戶端完成。有兩種方案供選擇:
    一是Native層攔截並請求資料再返回給Html層去展示,這樣會增加工作量,也不利於職責的分離,所以放棄。
    二是直接使用JS請求資料,這樣會出現跨域訪問的問題,相比較來說還是這個比較容易解決的,採用CORS即可

  • Native呼叫JS
    Native層呼叫JS比較簡單,執行一段JS程式碼即可,如:javascript:callJS()

  • JS呼叫Native
    JS層呼叫Native,在Android上來說主要分為三種:
    一:通過WebView#addJavascriptInterface()進行對映,使用起來簡單,但是有安全風險,棄用
    二:自定義協議然後由Native層攔截並解析請求,使用起來複雜,容易和業務耦合,也不是最優選,棄用
    三:攔截JS#prompt()方法並解析,使用起來複雜,但是比第一種更安全,比第二種靈活,所以使用此方案

資原始檔獲取

資原始檔採取差異化更新方案,本地儲存一個標識,可以為版本號或者更新時間,這個可以和後端同學一起商量確定。
資原始檔下載還有推送之類的由於Html的侷限性,所以還是直接由Native層做比較合適,下面簡單講解下應用中的兩種更新方式:

  • 服務端推送下發
    可以通過整合第三方的推送服務,在客戶端收到更新推送後主動去請求下載差異化檔案
  • 主動請求
    可以在選擇合適的時機,如在應用啟動時去請求差異化檔案

資原始檔更新

根據差異化清單對資原始檔進行整合,存放在臨時目錄中,然後在第二次開啟應用時更換,並展示更新後的介面,達到熱更新的效果。

總結

本文只是概括的講了結構的內容,可能會遺漏一些要點,如果大家有什麼問題歡迎留言或者去GitHub上提交issue

作者開源了一個優雅的實現多型別的RecyclerView類庫 支援DataBinding Form表單錄入,跨多個RecyclerView拖動 Github地址:github.com/free46000/M…

相關文章