HybridAPP 经过JSBridge提供调用Native功能的接口,让混合开发中的『前端部分』能够方便地使用地址位置、摄像头甚至支付等 Native 功能。它的核心是 构建 Native 和非 Native 间消息通讯的通道,并且是 双向通讯的通道。javascript
原理:经过WebView提供的接口向js的context(window)注入一个对象或者方法,js调用时,直接执行对应的Native代码逻辑前端
iOSjava
UIWebVIew(iOS2+)和WKWebView(iOS8+)的调用方式有所区别android
//假设ios客户端约定方法名为nativeBridge
//UIWebView
window.nativeBridge(message);
//WKWebView
window.webkit.messageHandlers.nativeBridge.postMessage(message);
复制代码
Androidios
原理:经过WebView提供的addJavascriptInterface
方法给浏览器window
注入一个命名空间,而后给Web增长一些能够操做Java的反射。web
// addJavascriptInterface
mWebView.addJavascriptInterface(new Class(), 'android');
//@JavascriptInterface
public class Class(){
@JavascriptInterface
public void method(){
}
}
// js 代码
window.android.method();
复制代码
在 4.2 以前,Android 注入 JavaScript 对象的接口是 addJavascriptInterface,可是这个接口有漏洞,能够被不法分子利用,危害用户的安全,所以在 4.2 中引入新的接口 @JavascriptInterface(上面代码中使用的)来替代这个接口,解决安全问题。c#
iOSsegmentfault
在UIWebView内发起的全部网络请求,均可以经过delegate函数在Native层获得通知。这样,咱们就能够在UIWebView内发起一个自定义的网络请求,一般是这样的格式:jsbridge://methodName?param1=value1¶m2=value2api
因而Native 拦截的请求中,咱们只要发现是jsbridge://开头的地址,就不进行内容的加载,转而执行相应的调用逻辑。浏览器
缺点:
即便URL scheme连接有以上缺点,但由于它 支持 iOS6,因此为了实现兼容不少方案会使用这种方式
Android逻辑与iOS类似
使用prompt,console.log,alert方式,在android webview这一层能够重写这些方法。
通常常使用prompt,由于这个在js里使用的很少,用来和native通信反作用比较少。
prompt简单举例说明,Web页面经过调用prompt()
方法,安卓客户端经过监听onJsPrompt
事件,拦截传入的参数,若是参数符合必定协议规范,那么就解析参数,扔给后续的Java去处理。这种协议规范,最好是跟iOS的协议规范同样,这样跨端调起协议是一致的,但具体实现不同而已。好比:hybrid://action?arg1=1
这样的协议,而其余格式的prompt
参数,是不会监听的,即除了hybrid://action?arg1=1
这样的规范协议,prompt
仍是原来的prompt
。
Native调用js实际就是执行拼接js字符串,从外部调用对应方法,返回js执行结果。所以js方法必须放在全局的Window上
iOS
是经过UIWebView
组件的stringByEvaluatingJavaScriptFromString
方法来实现的,该方法返回js脚本的执行结果。
//UIWebView
result = [uiWebview stringByEvaluatingJavaScriptFromString:javaScriptString];
//WKWebView
[wkWebView evaluateJavaScript:javaScriptString completionHandler:completionHandler];
复制代码
Android
在 Kitkat(4.4)以前是使用webview的loadUrl
进行调用的:
webView.loadUrl("javascript:JSBridge.trigger('webviewReady')");
复制代码
而 Kitkat 以后的版本,也能够用 evaluateJavascript 方法实现:
webView.evaluateJavascript(javaScriptString, new ValueCallback<String>() {
@Override
publicvoidonReceiveValue(String value){
}
});
复制代码
参考: