Hybrid框架之交互通信篇
前言
雖然有些應(yīng)用在使用React Native或Weex開發(fā),但綜合來看,業(yè)內(nèi)還是以混合開發(fā)模式為主,從我們自家的App來看,H5業(yè)務(wù)所占比重越來越高,目前大概占到35%左右,因此一套好的Hybrid開發(fā)框架必不可少。
混合開發(fā)的一般原則為交互較少、上線周期短、展示性質(zhì)的頁面使用H5開發(fā),如節(jié)日活動頁、商品秒殺頁面等。Hybrid框架要考慮的事情非常多,如頁面加載速度、預(yù)加載及緩存機制、與原生交互通信、不同機型兼容等問題。
本文的關(guān)注點僅在于Hybrid框架交互通信的設(shè)計與實現(xiàn),框架的其他方面日后分享,感興趣的也可以留言探討。
交互通信類型
從大的范圍來看,可以分為三類:
- H5向Native通信,以下為常見場景:
- H5打開一個原生界面,H5只作為一個入口,后續(xù)邏輯均在原生界面處理
- H5喚起一個原生界面執(zhí)行一些邏輯,需要將結(jié)果返回給H5
- Native向H5通信
- 通常表現(xiàn)原生界面將某些結(jié)果傳給H5頁面或觸發(fā)某些H5的行為
- H5頁面之間通信
- 如果H5項目有多個獨立頁面,頁面之間可能需要通信
設(shè)計與實現(xiàn)
設(shè)計原則
交互通信實現(xiàn)
H5向Native通信
如果不用JavaScript注入的方式,最常見的做法是利用自定義的交互協(xié)議,通過public boolean shouldOverrideUrlLoading(WebView view, String url)攔截并進行原生處理。因此為了適應(yīng)上述提到的一些場景,協(xié)議的格式就尤為重要。
H5打開一個原生界面,H5只作為一個入口,后續(xù)邏輯均在原生界面處理,無需返回值給H5
對于這種需求,通常使用路由協(xié)議來實現(xiàn),如下:
sample://route/module ID/sub ID
Native端接收到H5觸發(fā)的此種協(xié)議,就會根據(jù)模塊ID及子ID跳轉(zhuǎn)到某個原生頁面。上述協(xié)議示例只是一種最通用的情況,還可按一定規(guī)則擴展協(xié)議以應(yīng)對其他邏輯。關(guān)于模塊路由的設(shè)計可參考之前的一篇文章:一種Android客戶端架構(gòu)設(shè)計分享。
H5喚起一個原生界面執(zhí)行一些邏輯,執(zhí)行完成后需要將結(jié)果返回給H5
常見的示例如H5中調(diào)用原生的登錄模塊,用戶登錄成功后重新返回到H5頁面,同時需要將登錄狀態(tài)、用戶Urid等返回;另一種場景如H5調(diào)用原生地址管理模塊,選擇一個地址之后,將地址數(shù)據(jù)返回給H5。這兩個例子雖然也可以完全用H5實現(xiàn),從而避免交互,但采用H5與原生交互的方式優(yōu)點如下:
對于這種需求,其實就是一種需要帶回調(diào)的通信,即H5跳轉(zhuǎn)原生界面執(zhí)行完某操作后,需要將結(jié)果返回給H5。
以H5調(diào)用原生登錄并返回H5刷新為例,可設(shè)計協(xié)議如下:
sample://login/callback
Native端接收到此類協(xié)議則會調(diào)用原生登錄界面,同時保存下callback。當(dāng)原生界面登錄完成,可使用消息分發(fā)機制(一種Android客戶端架構(gòu)設(shè)計分享 中也有說明)通知WebView調(diào)用此JavaScript回調(diào),所需的傳值如登錄狀態(tài)、用戶ID可封裝為JSON格式,通過callback參數(shù)方式返回給H5。H5中處理此回調(diào)提取返回值,如登錄成功,接下來可執(zhí)行用戶登錄后相關(guān)的刷新操作。
Native向H5通信
普通的單向交互
此種通信方式比較簡單,就是通過WebView去加載JavaScript的方法或回調(diào)函數(shù),傳值可通過參數(shù)方式,跟上文的callback相同。
Native容器(Activity或ViewController(iOS))向H5暴露生命周期狀態(tài)
在混合開發(fā)中,往往為了模擬原生任務(wù)棧的效果,每打開一個新的H5總會開一個新的包含WebView的Activity(或者WebView也可直接位于Fragment中,Fragment位于Activity中)。這樣用戶體驗就接近原生效果,返回時會返回上一級包含H5頁面的Activity。
一種場景如A頁面跳轉(zhuǎn)到B頁面,從B頁面返回A頁面,此時純H5對頁面狀態(tài)不易監(jiān)測或者監(jiān)測不準(zhǔn)確,有時H5端會有此種需求,因此可利用原生頁面的生命周期獲取頁面狀態(tài)。在原生代碼中根據(jù)原生頁面的生命周期觸發(fā)一個JS回調(diào),有需要監(jiān)聽頁面生命周期的H5自行實現(xiàn)該回調(diào)即可,實現(xiàn)后JS即可獲取原生頁面狀態(tài)從而進行對應(yīng)處理。
由于H5沒必要知道原生界面的所有生命周期狀態(tài),可能僅僅對如下兩種狀態(tài)感興趣:
因此協(xié)議可定義為:
sample://lifecircle/status
status狀態(tài)值為PAUSED或RESUME 。
注意事項:
H5頁面之間的通信
對于SPA(Single Page Application),此為單頁面應(yīng)用,多個鏈接的跳轉(zhuǎn)都在同一個WebView中,上述需求是不必要的,此種實現(xiàn)體驗不太好。
對于MPA(Multiple Page Application),此為多頁面應(yīng)用,為了追求原生體驗,往往每一個H5總會新開一個Activity頁面,前文也有提到,MPA是我起的名字,理解意思即可。在這種情況下,不同的H5頁面實際上是處于不同的Activity或Fragment中,也是在不同的WebView中,因此H5頁面間的通信成為必要。
假設(shè)一種場景如A頁面打開B頁面,B頁面打開C頁面,C頁面需要向A頁面通信,之間隔著B頁面。理論上兩個通信的頁面間可以有0~N個中間頁,都能夠支持。
由于是不同的Activity和不同的WebView,因此H5頁面之間無法直接通信。有了上文講到的H5和Native之間互相通信的基礎(chǔ),此處可以換一個思路,將H5與H5的通信轉(zhuǎn)化為兩個Native頁面的通信。
下面是一個原理圖:
原理說明:
前提條件為模擬原生頁面回退棧的效果,每個Web頁都用單獨的WebView打開。
上圖例子中有3個Web頁面,邏輯為A頁面打開B頁面,B頁面打開C頁面,以C頁面的H5向A頁面的H5通信為例。
H5頁面間通信原理本質(zhì)是利用原生頁面間的通信方式。H5頁面的直接容器為WebView,再往外一層的容器為Activity(Android)或ViewController(iOS),為了兼容嵌入式的WebView,H5最好向WebView注冊事件而不要向Activity注冊。在實現(xiàn)上應(yīng)抽象封裝一個公共的WebView(相信大家日常開發(fā)中都是這樣做的),統(tǒng)一接收H5事件注冊及事件觸發(fā)通知。
首先A頁面的H5需要向容器注冊事件,JS需要調(diào)用的注冊協(xié)議為:
sample://register/custom_event_name
**注意:**custom_event_name為開發(fā)者自定義的事件名稱,不同頁面可注冊相同的事件名,那么多個頁面都會響應(yīng)事件;一個頁面中若注冊多個相同的事件名,則會覆蓋,僅響應(yīng)一次,也不推薦如此使用。
注冊完成后,每個容器實例會維護一個注冊過的事件名列表。
當(dāng)C頁面要向A頁面通信時,C頁面中JS需要觸發(fā)的協(xié)議為:
sample://notify/custom_event_name/callback/params
**注意:**custom_event_name要跟注冊事件名一致,Native端用來匹配決定哪個頁面響應(yīng)事件;callback則為A頁面收到消息后要執(zhí)行的回調(diào);params為H5間通信需要傳遞的參數(shù),即為A頁面執(zhí)行callback回調(diào)時的參數(shù),其格式根據(jù)需求可自定義,復(fù)雜的數(shù)據(jù)可使用JSON串。事件名稱、回調(diào)名稱、回調(diào)參數(shù)可自由定義,均跟Native端無關(guān)。
協(xié)議sample://notify/custom_event_name/callback/params中的callback需要在A頁面的H5中實現(xiàn),否則無法響應(yīng)C中H5對A中H5的通信。
上述過程中,原生容器C向A通信也是利用一種Android客戶端架構(gòu)設(shè)計分享 中介紹的消息分發(fā)機制。當(dāng)然也可以用EventBus之類的事件總線替代,在iOS中可使用廣播實現(xiàn)。
總結(jié)
Hybrid框架中的交互通信主要是以上幾種,這些基本能夠滿足日常開發(fā)需求。交互原理也比較簡單,如有其它特殊交互也可擴展,相信大家能夠根據(jù)上述設(shè)計原理自己實現(xiàn),有時間的話后面會提供一個框架實現(xiàn)的demo。
總結(jié)
以上是生活随笔為你收集整理的Hybrid框架之交互通信篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中的scrapy爬虫_Pyt
- 下一篇: Windows 7镜像安装Windows