前言
移動開發的跨平臺與快速釋出一直是開發者的追求,也是技術的一個發展趨勢,現在各大廠開始有了自己的大前端團隊,所以我們也開始了自己的探索,目前來說主要有兩種思路:
Hybrid App
代表:Cordova
通過Webview
載入Web
頁面,在Native
和Web
頁面之間建立雙向通訊H5
程式碼Native
化 代表:ReactNative
,Weex
等
使用各平臺Api
,把H5
程式碼編譯成二進位制程式碼直接執行
其實關於這兩種思路對比,網上有很多大牛分析的很全面了,總結來說各有利弊很難完美,本篇文章我們主要講一下Hybrid App實踐,採用前後端分離以及單頁應用技術開發Web
頁面,使用WebView
載入Web
頁面,並通過JS
通訊提供一些Native
層的支援,通過介面獲取差異化頁面資原始檔,在本地整合更新,還可以達到熱更新的需求。在我看來此方案更適用於需要快速釋出、多端相容、對效能要求稍低的業務,正好符合我們的需求。
原始碼
這裡我整理了Android
端會用到程式碼,包含JS
通訊,檔案處理工具類,閃屏輔助類和WebView
的封裝。
Github地址:github.com/free46000/H…,請大家多多關注,由於原始碼並沒有完善,所以暫時沒有釋出到Maven
倉庫
方案詳解
既然確定了方向,那麼就應該確定具體的方案了,通過自己的經驗和網上資料整理,畫了時序圖:
按照圖上的時序,接下來說一下每一步中的實踐,以及碰到的坑。下面講解
初次安裝
- 打包
在打包程式時這一步主要是把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…