Android原生與H5通信
如今,混合開發似乎成為了主流。H5擁有跨平臺的優勢,卻存在性能上的問題正好可以用搭建原生殼承載H5代碼的方式去解決。
如何理解這種方式,就好像說Android原生代碼封裝外殼,內部包含H5代碼作為核心內容。更細節一點,我們把引導頁、登錄頁、首頁等等與業務關聯打不并且與用戶交互較多的頁面用原生去寫,而業務頁面,邏輯代碼由H5處理,將他們結合就形成了混合開發的由原生殼承載的H5APP。
這么做有什么好處呢?組個例子,我們利用這種方式做好了一個Android原生APP,現在需要做一個IOS原生APP,我們可以直接簡單搭建一個IOS殼,復用H5代碼,完成IOS原生APP。同時我們需要在釘釘、微信小程序等等平臺搭建,可以直接復用我們已有的H5代碼。
而這樣的搭建方式比純H5搭建的APP的優勢在于因為有原生殼的存在,可以自由的使用原生API。保證了交互上的流暢性。
如何實現原生與H5的通信呢?
關于通訊我們需要解決兩個問題:
- 原生向H5通訊
- H5向原生通訊
第一個問題很好解決,以Android為例,WebView提供特有的方法,當你打開一個Html,你可以去調用這個Html中包含的JS。例如:
- webview.loadUrl("javascript:callH5('Android ok')");
第二個問題我們采用發送指令的方式來處理。同樣以Android為例,WebView可以攔截html跳轉時的url地址,我們可以利用這個地址,約定一個規則,如果符合規則,則攔截后不執行跳轉,通過這個url獲取我們需要的信息,執行對應的操作。
- window.location.href=protocol://android?code=toast&data=+Json.stringify(config)
上述是一段JS的頁面跳轉方法。我們規定規則PRE=protocol://android?,當我們攔截的url包含PRE時,則我們認為這是一條指令,不需要跳轉頁面,應該執行對應操作。而參數code則是我們的指令內容,data為通信時的傳參。
接下來是原生這邊處理。首先我們攔截url。這里筆者還處理由于Http攻擊導致H5頁面出現廣告的問題。我們主要是第一個if。
- webView.setWebViewClient(new WebViewClient() {
- // Load opened URL in the application instead of standard browser
- // application
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- showLogInfo("攔截到的url----"+url);
- String advertising="http://"+sharedPreferencesUtil.getData(Constant.IP, RequestConfig.IP)
- +":"+sharedPreferencesUtil.getData(Constant.PORT,RequestConfig.IPPORT);
- if (url.contains(pre)) {
- Map map = getParamsMap(url, pre);
- String code = map.get("code");
- String data = map.get("data");
- parseCode(code, data);
- return true;
- }else if(!url.contains(advertising)){
- showLogError("攔截到植入廣告,廣告的url——"+url);
- return true;
- } else{
- return false;
- }
- }
- });
return 為ture表示攔截成功,不執行后面的跳轉操作。而false表示按正常流程執行。攔截成功后我們從url中獲取code和data,接著就可以按照我們自己的需求去處理了。