JSBridge 原理详解

什么是 JSBridge

JSBridge 是 WebView 中 JavaScript 与 Native 代码之间的通信桥梁。核心问题是:两个不同运行环境的代码如何互相调用?


通信原理

1. Native 调用 JS(简单)

WebView 本身就提供了执行 JS 的能力,原理很直接:WebView 控制着 JS 引擎,可以直接向其注入并执行代码。

java 复制代码
// Android
webView.evaluateJavascript("window.appCallJS('data')", null);

// iOS
webView.evaluateJavaScript("window.appCallJS('data')")

// Flutter
webViewController.runJavaScript("window.appCallJS('data')");

2. JS 调用 Native(核心难点)

JS 运行在沙箱中,无法直接访问系统 API。有两种主流方案:

方案一:注入 API

Native 在 WebView 初始化时,向 JS 全局对象注入方法:

java 复制代码
// Android - 注入对象到 window
webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void showToast(String msg) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    }
}, "NativeBridge");

JS 端直接调用:

javascript 复制代码
window.NativeBridge.showToast("Hello")

本质:Native 把自己的方法"挂"到了 JS 的全局作用域里。

方案二:URL Scheme 拦截

JS 发起一个特殊协议的请求,Native 拦截并解析:

javascript 复制代码
// JS 端
location.href = 'jsbridge://showToast?msg=Hello'

// 或使用 iframe(避免页面跳转)
const iframe = document.createElement('iframe')
iframe.src = 'jsbridge://showToast?msg=Hello'
document.body.appendChild(iframe)
java 复制代码
// Android 端拦截
webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("jsbridge://")) {
            // 解析 url,执行对应 Native 方法
            return true;
        }
        return false;
    }
});

本质:利用 WebView 的 URL 加载机制作为通信通道。


异步回调的实现

JS 调用 Native 后如何拿到返回值?通过回调 ID 机制:

javascript 复制代码
// JS 端
let callbackId = 0
const callbacks = {}

function callNative(method, params) {
    return new Promise((resolve) => {
        const id = callbackId++
        callbacks[id] = resolve
        // 告诉 Native:调用完成后,用这个 id 回调我
        window.NativeBridge.invoke(JSON.stringify({
            method,
            params,
            callbackId: id
        }))
    })
}

// Native 执行完后调用这个函数
window.handleCallback = (id, result) => {
    callbacks[id]?.(result)
    delete callbacks[id]
}

流程 :JS 调用 → Native 处理 → Native 调用 evaluateJavascript 执行回调函数 → JS 收到结果


各平台注入对象命名

平台/插件 全局对象名 是否可自定义
Android 原生 任意 ✅ 完全自定义
iOS WKWebView webkit.messageHandlers.xxx ✅ xxx 部分可自定义
flutter_inappwebview flutter_inappwebview ❌ 插件固定
webview_flutter 需要自己实现 ✅ 完全自定义

Android 示例

java 复制代码
// 第二个参数就是 JS 中的对象名,可以随便取
webView.addJavascriptInterface(bridgeObject, "MyBridge");
javascript 复制代码
// JS 端
window.MyBridge.method()

iOS 示例

swift 复制代码
// name 就是 JS 中的 handler 名
configuration.userContentController.add(self, name: "iOSBridge")
javascript 复制代码
// JS 端
window.webkit.messageHandlers.iOSBridge.postMessage(data)

Flutter (flutter_inappwebview) 示例

dart 复制代码
// Flutter 端注册 handler,handlerName 可自定义
webViewController.addJavaScriptHandler(
  handlerName: 'myCustomHandler',
  callback: (args) { ... }
);
javascript 复制代码
// JS 端,flutter_inappwebview 是固定的
window.flutter_inappwebview.callHandler('myCustomHandler', data)

通信方式总结

方向 原理 实现方式
Native → JS WebView 控制 JS 引擎 evaluateJavascript
JS → Native 注入或拦截 addJavascriptInterface / URL Scheme

常见通信方式对比

方式 优点 缺点 适用场景
JavaScript Bridge 双向通信、支持回调 需要约定协议 复杂交互
URL Scheme 简单、兼容性好 单向、数据量有限 简单跳转
postMessage 标准 API 需要 WebView 支持 iframe 通信
注入 JS 对象 调用方便 Android 4.2 以下有安全漏洞 频繁调用

最佳实践建议

  1. 统一封装:抽离成独立的 bridge 工具类,统一管理通信逻辑
  2. 消息队列:处理 Native 未就绪时的调用,避免丢失消息
  3. 超时处理:添加超时机制,防止回调永远不返回
  4. 类型安全:使用 TypeScript 定义消息类型
  5. 错误处理:统一的错误捕获和上报机制

科研投稿资源分享

如果您是计算机领域(AI / 大数据 / 网络 / 软件工程等)的研究者,近期有成果想投稿发表,这几个高认可度的国际会议可以参考(均支持 EI/SCOPUS 检索):

  1. 第七届计算机信息和大数据应用国际学术会议(CIBDA 2026)
  2. 第二届健康信息化与数据分析国际学术会议(HIDA 2026))
  3. 第八届IEEE通信、信息系统与计算机工程国际会议(IEEE-CISCE 2026)
  4. 2026年机器学习与大模型国际学术会议(ICMLM 2026)
相关推荐
代码搬运媛8 小时前
Jest 测试框架详解与实现指南
前端
counterxing9 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq9 小时前
windows下nginx的安装
linux·服务器·前端
之歆9 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜9 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai1080810 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
kyriewen11 小时前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
humcomm12 小时前
元框架的工作原理详解
前端·前端框架
canonical_entropy12 小时前
Attractor Before Harness: AI 大规模开发的方法论
前端·aigc·ai编程
zhangxingchao12 小时前
多 Agent 架构到底怎么选?从 Claude Agent Teams、Cognition/Devin 到工程落地原则
前端·人工智能·后端