JSBridge在Web端和Native端中间起到了一个桥梁作用,通过JSBridge Web端可以调用Native的Java接口,同样的Native端也可以通过JSBridge去调用Web端提供的JavaScript接口。从而实现Web端和Native端的双向调用。
所以JSBridge的实现可以分为两个部分:一方面是从Native触发,将事件传递给Web端;另一方面是从Web端触发,将请求传递给Native端。这就是JSBridge的双向通信。
从Web端触发,将请求传递给Native端有两种方式: 1.拦截WebView请求的URL Schema。2.向WebView注入JS API。
(1)拦截WebView请求的URL Schema:
URL Schema是类URL的一种请求格式。比如:<protocol>://<domain>/<path>?<query>。我们可以通过自定义的JSBridge通信的URL Schema让Native能够进行拦截,然后在Native中去执行相应的逻辑。
对于Native,安卓提供了shouldOverrideUrlLoading方法拦截;UIWebView使用shouldStartLoadWithRequest,WKWebView则使用decidePolicyForNavigationAction。
这种方法的优点是:兼容性好。缺点是不直观、URL长度有限制。
(2)向WebView注入JS API:
这个方法会通过webView提供的接口,App将Native的相关接口注入到JS的Context(window)的对象中,一般来说这个对象内的方法名与Native相关方法名是相同的,Web端就可以直接在全局window下使用这个暴露的全局JS对象,进而调用原生端的方法。
以Andriod (4.2+)的addJavascriptInterface为例:
// 注入全局JS对象
webView.addJavascriptInterface(new NativeBridge(this), "NativeBridge");
class NativeBridge {
private Context ctx;
NativeBridge(Context ctx) {
this.ctx = ctx;
}
// 增加JS调用接口
@JavascriptInterface
public void showNativeDialog(String text) {
new AlertDialog.Builder(ctx).setMessage(text).create().show();
}
}
在Web端直接调用这个方法即可
window.NativeBridge.showNativeDialog('hello');
iOS的UIWebView提供了JavaSciptCore;iOS的WKWebView提供了WKScriptMessageHandler。
从Native触发,将事件传递给Web端:
Native 向 Web 发送消息基本原理是在 WebView 容器中动态地执行一段 JS 脚本,通常情况下是调用一个挂载在全局上下文的方法。webview是JS的解析器。Android 4.4之后提供了evaluateJavascript来执行JS代码,并且可以获取返回值执行回调: