IOS、Android與H5通信 原理淺析


IOS、Android與H5通信-JsBridge原理(總結)

H5和原生app(ios,android)交互的載體基本都是基於Webview,可以把Webview看作是一個性能打八折的移動瀏覽器。

ios調用Javascript

簡單說下這幾種:WKWebView 、UIWebView、JavaScriptCore

WKWebView:蘋果在ios8之后也引入了專門負責處理網頁視圖的框架WebKit,Webkit是啥,接觸過H5、chrome的肯定都知道。chrome使用的也是基於webkit內核的Chromium引擎。WKWebView優點很多,支持更多H5特性,刷新效率及內置手勢等,更加強大,性能也更優,不一一列舉,如果大家app不需要兼容7及以下版本,不需要攔截一些請求,直接解析本地一些文件,建議使用WKWebView。

UIWebView:較老webview,第一代。其中stringByEvaluatingJavaScriptFromString方法提供了OC與js交互的能力。

JavaScriptCore(ios7及以后版本)。JavaScriptCore框架是webkit重要組成部分,主要是對JS進行解析和提供執行環境,Javascript的虛擬機,有點類似v8引擎,我自己這么理解:)正是它為ios提供了執行JavaScript代碼的能力。ReactNative應該都是通過JavaScriptCore去解析的(自己猜測)。

微信小程序的邏輯層也是由JavaScriptCore作為運行環境。

Javascript 調用 ios(oc、swift)原理:

目前兼顧兼容性、比較成熟的方案還是通過攔截URL的方式。

UIWebView的特性,在UIWebView內發起的所有網絡請求,都可以在Native層被捕捉到。

利用這一特性,就可以在UIWebView內發起一個自定義的網絡請求,一般格式:jsbridge://method?參數1=value1&參數2=value2

於是在UIWebView中,只要發現是jsbridge://開頭的url,就不進行內容的加載,而是執行相應的邏輯處理。

嵌入webview的h5中的js一般是通過動態創建隱藏iframe標簽,賦值上文提到的鏈接給src,iframe不會引起頁面調轉、刷新。

主要代碼:

var src= 'jsbridge://method?參數1=value1&參數2=value2';

var iframe = document.createElement('iframe');

iframe.style.display = 'none';

iframe.src = src;

document.body.appendChild(iframe);

//再刪除

iframesetTimeout(function() {

  iframe.remove();

}, 50);

Android和Javascript互相調用

Android WebView也是基於WebKit引擎的一個組件,Android的Webview在低版本和高版本采用了不同的webkit版本內核,4.4后直接使用了Chrome。

這個組件功能非常強大,除了具有一般View的屬性和設置外,還可以對url請求、頁面加載、渲染、頁面交互進行強大的處理。

Android調用JS代碼的方法主要有2種:

1、WebView的loadUrl

2、WebView的evaluateJavascript

JS調用Android代碼的方法主要有3種:

1、WebView的addJavascriptInterface進行對象映射(低版本Android4以下好像有一些安全問題,本人沒有驗證)

2、WebViewClient 的 shouldOverrideUrlLoading 方法回調攔截 url

3、WebChromeClient 的onJsAlert、onJsConfirm、onJsPrompt方法回調攔截JS對話框alert()、confirm()、prompt() 消息

一般常用onJsPrompt、prompt進行回調攔截

JSBridge是Native代碼與JS代碼的通信橋梁

設計一個jsbridge主要分幾大步驟:

第一步:設計出一個Native與JS交互的全局中間對象

第二步:JS如何調用Native

第三步:Native如何得知api被調用

第四步:分析url-參數和回調的格式

第五步:Native如何調用JS

第六步:H5中api方法的注冊以及格式

 

結合場景運用:

運用場景描述:在H5端點擊頁面的發送按鈕通知APP打開微信分享功能,交互寫在發送事件函數中,調起微信分享功能由app端操作

//給到app的json參數 let jsonData = { reload: this.$route.query.no_reload ? false : true, //true需要重新加載返回列表頁,false不需要(根據需求定) title: '上門試駕邀請', // 分享標題 desc: '邀請您試駕體驗xxxx', // 分享描述 link: 'https://xxxxx', // 分享鏈接 imgUrl: '', // 分享圖標 } 

 判斷設備

device() { let u = window.navigator.userAgent; //android終端 let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //ios終端 let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); return {android: isAndroid, ios: isiOS} },

JS與IOS交互方式一:WKScriptMessageHandler

WKWebView有一個內容交互控制器,該對象提供了通過JS向WKWebView發送消息的途徑。需要設置MessageHandler,大家把這個功能簡稱為MessageHandler。

IOS具體實現參考:鏈接

這里只說js調用

/ window.webkit.messageHandlers.<name>.postMessage(<messageBody>) // 這個name就是設置MessageHandler的第一個參數,與IOS約定的方法名 // messageBody 必須是json格式,為空時傳null window.webkit.messageHandlers.ShareContract.postMessage(jsonData);

JS與IOS交互方式二:WebViewJavascriptBridge交互 攔截url做事件處理,如果要傳參數,不建議用這種

//模擬 h5頁面在app端的跳轉 let data = '{"type": "basisTongji", "url":"' + "https://xxxx/basisTongji.html" + "}"; window.WebViewJavascriptBridge.javaScrpitRresponseJson(data);

Android端交互

 

冒號前面區分是什么功能,冒號后面是接收的參數

window.location.href = "ShareContract:" + JSON.stringify(jsonData);


運用場景二:登錄失效的情況下,通知APP端,需要跳轉到登錄頁面

  • exit:true是和安卓約定的功能名及參數
  • logout 是和IOS約定的方法名,注意當值為空的時候,需要傳null,不能什么都不寫,不然會走代理。。。
let deviceP = device() if (deviceP.android) { window.location.href = "exit:true" } if (deviceP.ios) { //ios 交互 window.webkit.messageHandlers.logout.postMessage(null); }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM