H5嵌入APP后,原生APP與H5之間交互


原生APP跳轉到H5頁面時,往往需要攜帶一些用戶信息,之前做法是在跳轉的地址中拼接H5頁面需要的參數,現在通過window.WebViewJavascriptBridge悄悄的進行數據交互。

本文主要從H5的角度記錄交互思路:

1:安卓環境和ios環境稍微有點不同,需要根據navigator.userAgent判斷一下當前環境

2:仍然是APP環境不同,安卓需要進行兼容性判斷,如果不存在window.WebViewJavascriptBridge變量,需要手動添加Dom的WebViewJavascriptBridgeReady事件監聽;ios同樣需要判斷是否存在window.WebViewJavascriptBridge變量,如果不存在繼續判斷window.WVJBCallbacks變量,如果仍然不存在,則手動賦值為H5回調,然后document.createElement('iframe')插入document中,隨即移除。

3:以上處理完成后,通過WebViewJavascriptBridge變量來注冊【事件】以便APP能監聽到並執行相應操作

4:3中需要對安卓系統進行init處理,如果是安卓系統,注冊事件之前需要先調用WebViewJavascriptBridge.init()

方法(注意: 一個頁面整個生命周期過程中,只能進行一次init()否則會報錯,我的做法是通過一個全局變量來判斷是否初始化過)

以下是具體代碼:

//針對安卓和ios系統,對window.WebViewJavascriptBridge進行兼容性處理
function setupWebViewJavascriptBridge(callback) {
	var u = navigator.userAgent;
	var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android終端
	var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
	if (isAndroid) {
		if (window.WebViewJavascriptBridge) {
			callback(WebViewJavascriptBridge)
		} else {
            //添加dom事件
			document.addEventListener(
				'WebViewJavascriptBridgeReady',
				function () {
					callback(WebViewJavascriptBridge)
				},
				false
			);
		}
			
	}
	if (isiOS) {
		console.log('isiOS')
		if (window.WebViewJavascriptBridge) {
			return callback(WebViewJavascriptBridge);
		}
		if (window.WVJBCallbacks) {
			return window.WVJBCallbacks.push(callback);
		}
		window.WVJBCallbacks = [callback];
		var WVJBIframe = document.createElement('iframe');
		WVJBIframe.style.display = 'none';
		WVJBIframe.src = 'https://__bridge_loaded__';
		document.documentElement.appendChild(WVJBIframe);
		setTimeout(function () {
			document.documentElement.removeChild(WVJBIframe)
		}, 0)
	}
}
//封裝方法,key:跟原生定義好的要捕獲的名稱, callback:原生捕獲后執行的回調,此處可以寫H5的后續執行方法,params:對象,要傳給原生的參數
var setupWebViewBridge = function (key, callback, params) {
	setupWebViewJavascriptBridge(function (bridge) {
		var u = navigator.userAgent;
		var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android終端
		var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
        //自己定義的全局變量,用來判斷當前頁面中安卓系統是否進行過一次初始化,頁面卸載時取消賦值
		if (!window.hadCalledWindow_WebViewJavascriptBridge ) {
			if (isAndroid) {
				window.hadCalledWindow_WebViewJavascriptBridge = true 
				bridge.init(function (message, responseCallback) {
					console.log('JS got a message', message);
					var data = {
						'Javascript Responds': '測試中文!'
					};
 
					if (responseCallback) {
						console.log('JS responding with', data);
						responseCallback(data);
					}
				});
			}
		}
		bridge.callHandler(
			key,
            //安卓系統必須傳一個參數,否則捕獲不到,因此,默認傳入一個_x_變量 
			JSON.stringify({
				...params,
				_x_: 1,
			}),
			callback
		);
 
	})
}

原生APP里,注冊要捕獲的方法:

bridge.registerHandler('jsbridge_showMessage', function (data, responseCallback) {
             showResponse(data);
         });

轉載來源於 https://blog.csdn.net/haoyanyu_/article/details/89237819

移動端混合開發,需要原生與h5交互。
目前接觸過的兩種方法:

  1. 大多數是直接通過webview代理,理解的是通過攔截調用與原生進行交互。任意版本都支持。
  2. 使用第三方庫WebViewJavaScriptBridge。
    這里主要整理下WebViewJavaScriptBridge在前端部分的使用:
    【用於 WKWebView & UIWebView 中 OC 和 JS 交互(ios)】

注冊監聽事件(固定代碼):

/*這段代碼是固定的,必須要放到js中*/
function setupWebViewJavascriptBridge(callback) {
	if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
	if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
	window.WVJBCallbacks = [callback];
	var WVJBIframe = document.createElement('iframe');
	WVJBIframe.style.display = 'none';
	WVJBIframe.src = 'https://__bridge_loaded__';
	document.documentElement.appendChild(WVJBIframe);
	setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)

js與原生方法調用部分

//添加原生調起js方法
setupWebViewJavascriptBridge(function(bridge) {
     /* Initialize your app here */
     //所有與iOS交互的JS代碼放這里!

    //js注冊方法讓原生調起(原生調用js)
    
    //name: 和原生約定的調用方法名
    //function(data,callback):調用方法的具體內容,data為原生傳過來的參數,callback為js給原生的回調函數             
    bridge.registerHandler("jsFunction",function(data,responseCallback){
        alert("do sth with"+data)
        responseCallback("js calls back to oc");
    });
    
    
    //js喚起原生注冊的方法(js調用原生)
    
    //name: 和原生約定的調用方法名
    //data: 向原生傳遞的參數
    //function: 原生調用后的回調函數(回調結果處理)
    bridge.callHandler('ocFunction',data,function(res){
         alert("js has received the result:"+res);
    });
}

備注:


免責聲明!

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



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