在webView 中使用JS 调用 Android / IOS的函数 Function

时间:2022-06-01 20:52:46

最近做一个项目,混合了NativeCode 和 HTML,为了便于JS 调用App的一些方法,统一封装一个Js方法,记录如下

Android 端首先要再WebView中允许JS的调用

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new WebAppInterface(this), "JsAndroid");

IOS端使用的是一个开源库 EasyJsWebView,在IOS端引用即可

JS代码:

function callApp(method) {
var args = [].slice.call(arguments).splice(1);
var s = "";
if (/android/i.test(navigator.userAgent)) {//安卓
s = window["JsAndroid"][method].apply(window.JsAndroid, args);
}
if (/ipad|iphone|mac/i.test(navigator.userAgent)) {//ios
s = window["JsIOS"][method].apply(this, args);
}
return s;
} //与IOS交互的方法
window.EasyJS = {
__callbacks: {}, invokeCallback: function (cbId, removeAfterExecute) {
var args = Array.prototype.slice.call(arguments).splice(2); for (var i = 0, l = args.length; i < l; i++) {
args[i] = decodeURIComponent(args[i]);
} var cb = EasyJS.__callbacks[cbId];
if (removeAfterExecute) {
EasyJS.__callbacks[cbId] = undefined;
}
return cb.apply(null, args);
}, call: function (obj, functionName, args) {
var formattedArgs = [];
for (var i = 0, l = args.length; i < l; i++) {
if (typeof args[i] == "function") {
formattedArgs.push("f");
var cbId = "__cb" + (+new Date);
EasyJS.__callbacks[cbId] = args[i];
formattedArgs.push(cbId);
} else {
formattedArgs.push("s");
formattedArgs.push(encodeURIComponent(args[i]));
}
} var argStr = (formattedArgs.length > 0 ? ":" + encodeURIComponent(formattedArgs.join(":")) : ""); var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "easy-js:" + obj + ":" + encodeURIComponent(functionName) + argStr);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null; var ret = EasyJS.retValue;
EasyJS.retValue = undefined; if (ret) {
return decodeURIComponent(ret);
}
}, inject: function (obj, methods) {
alert(obj);
window[obj] = {};
var jsObj = window[obj];
for (var i = 0, l = methods.length; i < l; i++) {
(function () {
var method = methods[i];
var jsMethod = method.replace(new RegExp(":", "g"), "");
jsObj[jsMethod] = function () {
alert("qq");
return EasyJS.call(obj, method, Array.prototype.slice.call(arguments));
};
})();
}
}
};

  

说明一下,一开始调用Android也是采用window["JsAndroid"][method].apply(this,args),这样的话,就完全一致了。但是在调试的时候发现这种方式无法正常调用,google后发现是由于this的的影响域导致的,需要指明查找域。 参考

记录一下!