JsBridge

66 阅读5分钟

一、什么是 JSBridge?

JSBridge,顾名思义,是连接 JavaScript 和 Native(原生客户端)  的桥梁。它是一种机制,允许运行在 WebView 中的 JavaScript 代码调用原生系统(如 Android 的 Java/Kotlin, iOS 的 Objective-C/Swift)的功能,同时也允许原生代码调用 JavaScript 函数。

核心目的:让 Hybrid App(混合模式移动应用) 中的 H5 页面能够使用原生能力,如相机、地理位置、文件系统、蓝牙等,从而突破纯网页技术的限制,获得接近原生应用的体验。


二、为什么需要 JSBridge?

  1. 动态化与灵活性:H5 页面可以随时上线和更新,无需经过应用商店的审核,非常适合业务快速迭代和 A/B 测试。
  2. 跨平台:一套 H5 代码,可以在 Android 和 iOS 两个平台上运行,节省开发成本。
  3. 功能互补:H5 无法实现或实现效果不佳的功能(如复杂的图形处理、高性能游戏、深度设备集成),可以由原生端提供,然后通过 JSBridge 供 H5 调用。
  4. 体验平衡:在保证大部分业务动态化的前提下,通过调用原生组件(如导航栏、弹窗),可以提升局部的用户体验。

三、JSBridge 的核心原理与实现方式

JSBridge 的本质是 双向通信。其实现主要依赖于 WebView 提供的交互能力。

1. JavaScript 调用 Native

这是最常用的方向。主要有三种主流方案:

a) 拦截 URL Scheme(最常用、最经典)

这是最普遍的实现方式。

原理

  1. JavaScript 通过创建一个 iframe 或直接修改 window.location,发起一个特殊的伪协议 URL 请求。

    • 例如:jsbridge://showToast?title=hello&duration=2000
  2. Native 端会监听 WebView 的所有请求。当它发现这个请求的 Scheme(这里是 jsbridge://)是事先约定好的协议时,就不会进行真正的网络请求,而是拦截这个请求。

  3. Native 端解析这个 URL,获取到方法名showToast)和参数{title: ‘hello’, duration: 2000})。

  4. Native 端执行对应的原生方法。

  5. (可选)执行完毕后,Native 通过其他方式将结果回调给 JavaScript。

优点:兼容性好,几乎所有版本的 WebView 都支持。
缺点:URL 长度有限制,传递大量数据时可能有问题;调用是单向的,获取返回值需要额外的回调机制。

b) 向 JavaScript 注入 API(Android 4.2+ 推荐)

原理

  1. Native 端在 WebView 加载页面时,通过 WebView 的接口(Android 的 addJavascriptInterface,iOS 的 JavaScriptCore 或 WKScriptMessageHandler)向 JavaScript 上下文(window)中注入一个全局对象。

  2. JavaScript 可以直接调用这个全局对象上的方法。

    • 例如:window.NativeBridge.showToast(‘hello’, 2000)

优点:调用方式更直观、自然,就像调用本地函数一样;性能较好。
缺点

  • Android:在 4.2 以下有严重安全漏洞(漏洞详情与 addJavascriptInterface 有关)。虽然 4.2+ 已修复,但兼容低版本需要额外处理。
  • iOSUIWebView(已废弃)和 WKWebView 的注入方式不同,需要分别处理。
c) 弹窗拦截(已过时,了解即可)

早期通过 JavaScript 的 alertconfirmprompt 方法触发,Native 端拦截这些弹窗并解析其中的信息。因其会阻塞线程且功能有限,现已很少使用。


2. Native 调用 JavaScript

这个方向相对简单。

原理
Native 端通过 WebView 的 loadUrl 方法或 evaluateJavascript 方法,直接执行一段 JavaScript 字符串代码。

  • Android:

    java

    // 4.4 之前
    webView.loadUrl("javascript:handleFromNative('" + message + "')");
    
    // 4.4+ 推荐
    webView.evaluateJavascript("javascript:handleFromNative('" + message + "')", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            // 这里可以拿到 JavaScript 函数的返回值
        }
    });
    
  • iOS (WKWebView) :

    objc

    [webView evaluateJavaScript: "javascript:handleFromNative('message')" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        // 处理返回结果或错误
    }];
    

四、一个完整的 JSBridge 设计流程

一个成熟的 JSBridge 不仅仅是通信,还包括回调管理、消息队列等。

  1. 初始化:H5 页面加载后,检查 Native 注入的全局对象是否存在。如果不存在,则降级为使用 URL Scheme 方式。

  2. JavaScript 调用 Native

    • H5 生成一个唯一的 callbackId
    • 将 callbackId、方法名、参数组装成一个消息。
    • 在 H5 端创建一个以 callbackId 为 key 的回调函数,存入一个回调字典中。
    • 通过 URL Scheme 或注入的 API 将消息发送给 Native。
  3. Native 处理

    • Native 解析消息,执行对应的原生功能。
    • 执行完毕后,携带结果数据和接收到的 callbackId,调用 H5 的一个统一接收函数。
  4. Native 回调 JavaScript

    • H5 的统一接收函数被调用,根据 callbackId 从回调字典中找到对应的回调函数。
    • 执行该回调函数,并将 Native 返回的数据传入。
    • 从字典中移除已执行的回调。
  5. 消息队列:在 Bridge 尚未准备就绪时(例如,H5 的 Bridge JS 文件已加载,但 Native 尚未注入对象),可以将调用请求先存入一个队列,待 Bridge 准备好后再依次执行。


五、实际应用与现有库

在实际开发中,我们很少从零开始实现一整套 JSBridge。通常会使用成熟稳定的库或框架。

  • DSBridge:一个非常优秀的开源库,同时支持 Android 和 iOS,API 设计简洁,同时支持上述的两种调用方式,并且提供了同步调用能力。
  • WebViewJavascriptBridge (iOS):一个经典的、在 iOS 端广泛使用的库。
  • 官方推荐:现在更推荐使用 WKWebView 的 postMessage 机制,或者 Google 推出的 PWA + Trusted Web Activity 方案来构建混合应用,它们提供了更现代、更安全的通信方式。

总结

特性描述
本质JavaScript 与 Native 代码之间的双向通信通道
核心目的让 H5 能够调用原生能力,实现 Hybrid App 的动态化和功能互补。
主要实现方式JS 调 Native:拦截 URL Scheme、注入 API。Native 调 JSevaluateJavascript / loadUrl
关键设计消息格式、回调管理、桥接器就绪机制。

JSBridge 是混合开发技术的基石,理解它对于开发高性能、高体验的 Hybrid App 至关重要。