JSBridge
原生APP开发中有一个叫WebView的组件,这个组件可以加载HTML文件。JSBridge则是WebView内的JS环境与Native沟通的一个渠道,它允许WebView去调用原生的API(比如拍照,截屏,录屏等),极大的扩展了WebView的功能

WebView
WebView是移动端提供的运行JS的环境,是系统渲染Web网页的一个控件,可与JS交互,实现了混合开发。WebView除了能加载指定URL外,还可以对URL请求,JS对话框,进度加载,页面交互进行处理
JSBridge实现原理
Web端和Native可以类比于Client/Server模式,Web端调用原生接口时,就如同Client向Server端发送一个请求,JSBridge在此充当类似于HTTP协议的角色,实现JSBridge主要是两点:
- 将Native端原生接口封装为JS接口
- 将Web端JS接口封装成原生接口
Native端到Web端比较简单,JS作为解释型语言,可以随时随地通过解释器执行一段代码,所以可以将拼接的JS代码字符串传入JS解释器即可
Android 4.4以前,只能通过loadUrl来实现,并且无法执行回调:
String jsCode = String.format("window.showWebDialog('%s')", text);
webView.loadUrl("javascript: " + jscode);
Android 4.4之后,提供了evaluateJavascript来执行JS,并且可以获取返回值执行回调:
String jsCode = String.format("window.showWebDialog('%s')", text);
webView.evaluateJavascript(jsCode, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
}
});
URL Scheme
URL Scheme是类URL的一种请求格式,格式如下:
<protocol>://<host>/<path>?<query>#fragment
我们可以自定义JSBridge通信的URL Scheme,比如:jsbridge://showToast?text=hello
,Native加载WebView之后,Web发送的所有请求都会经过WebView组件,所以Native可以重写WebView里的方法,从而拦截Web发起的请求,对请求的格式进行判断:
- 如果符合我们自定义的URL Scheme,对URL进行解析,拿到相关操作,进而调用原生Native的方法
- 如果不符合自定义的URL Scheme,直接转发,请求真正的服务
这种方式从早期就存在,兼容性很好,但是是基于URL的方式,长度受到限制并且不太直观,数据格式有限制,而且建立请求时间耗时
向WebView注入JS API
这个方法会通过WebView提供的接口,APP将Native相关的接口注入到JS的Context(window)中,一般来说,这个对象内的方法名与Native相关方法名是相同的,Web端就可以直接在全局window下使用这个暴露的JS对象,进而调用Native端的方法,这个过程会更直观简单,不过存在兼容性问题
webView.addJavascriptInterface(new NativeBridge(this), "NativeBridge");
class NativeBridge {
private Context ctx;
NativeBridge(Context ctx) {
this.ctx = ctx;
}
@JavascriptInterface
public void showNativeDialog(String text) {
new AlertDialog.Builder(ctx).setMessage(text).create().show();
}
}
在Web端直接调用这个方法即可:
window.NativeBridge.showNativeDialog("hello");
with Callback
目前站在一端的角度而言,还是一个单向通信的过程
但其实稍微修补一下之前的思路,就能实现调用并获取返回值的操作了:在一段调用时,在参数中加一个callbackId
标记对应的回调,对端收到调用请求后,进行实际操作,如果带有callbackId
,对端再进行一次调用,将结果、callbackId
回传回来