目前H5与原生交互的主要方式:
拦截Webview请求的URL Schema
URL Schema是类URL的一种请求格式,可以自定义JSBridge通信的URL Schema,比如:jsbridge://showToast?text=hello ,Native对符合约定的URL进行解析,拿到相关操作、操作,进而调用原生Native的方法,主要有:
a标签
location.href
使用iframe.src
-
发送ajax请求
但是,a标签需要用户操作;location.href可能会引起页面的跳转丢失调用;发送ajax请求Android没有相应的拦截方法;所以使用iframe.src是比较好的方案。总结:针对这种拦截Webview请求的URL Schema的交互方式,虽然兼容性还行,但是基于URL的方式,长度受到限制而且不太直观,数据格式有限制,而且建立请求有时间耗时。
JavascriptInterface
//对应安卓端 android为原生自定义
javascript:android.getSomething()
//对应ios端 h5向原生发送消息msg
window.webkit.messageHandlers.getSomething.postMessage(msg)
//注册供原生调用返回参数的方法
window.getSomething =(result)=>{
console.log('原生给H5的数据内容',result)
}
jsbridge
//定义与初始化 jsbridge.js
//注册事件监听,初始化
function setupWebViewJavascriptBridge(callback) {
if(isAndroid){
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
if(isIos){
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function(){
document.documentElement.removeChild(WVJBIframe);
}, 0);
}
}
//回调函数,接收数据
if(isAndroid) setupWebViewJavascriptBridge(function(bridge) {
//默认接收 安卓原生初始化
bridge.init(function(message, responseCallback) {
var responseData = 'js默认接收完毕,并回传数据给java';
responseCallback(responseData); //回传数据给java
});
//注册接收参数functionInJs名称 与原生保持一致
// bridge.registerHandler("functionInJs", function(data, responseCallback) {
// console.log('接收到的数据',data);
// var responseData = 'js指定接收完毕,并回传数据';
// responseCallback(responseData); //回传数据
// });
})
调用jsbridge
window.setupWebViewJavascriptBridge(bridge => {
// '原生函数名', "传给原生端的数据", callback 回调函数
bridge.callHandler('getSomething', data, (result) => {
console.log(result);
});
})
坑点:Android页面首次调用jsbridge时,返回较慢,后续返回正常,暂未找出原因