跳转至

架构概述

概述

WebView 环境包含两个独立的运行时:

  • JavaScript 运行时(Web 层)
  • 在 WebView 内部运行,执行 HTML/JS/CSS,处理 UI 和业务逻辑。

  • 原生 Android 运行时(Java/Kotlin 层)

  • 在 Android 应用内部运行,可访问设备功能(摄像头、GPS、文件、传感器、蓝牙等)。

由于这两个运行时无法直接通信,我们使用桥接——一种结构化的消息传递系统,在 JavaScript 和 Android 之间传递消息。

architecture-bridge-image

  • JavaScript 桥接是以下组件的组合:

    • 暴露给 JS 的原生对象(如 window.NativeBridge)或 postMessage API。
    • 消息协议(包含 actionidparams 等字段的 JSON 消息)。
    • 可选的消息队列、批处理和回调路由机制。
  • 原生 Android 为各操作实现处理器,执行设备操作后将结果返回给 JS。


架构层次

1. JavaScript 应用层

这是在 WebView 中运行的标准 JS 应用程序: - UI 交互 - 表单处理 - 页面导航 - 应用逻辑

通过简化的接口调用原生 API,例如:

const photo = await Native.call("takePhoto");

2. JavaScript 桥接层(客户端)

该层将 JavaScript 函数调用转换为结构化消息(通常是 JSON)。 其核心职责包括: - 创建消息包 - 分配唯一请求 ID - 向原生层发送消息 - 处理异步响应 - 在 JS 中解析或拒绝 Promise

JSON 请求示例:

{
  "id": "req-23",
  "action": "getLocation",
  "params": { "accuracy": "high" }
}

原生响应时:

{
  "id": "req-23",
  "status": "ok",
  "result": { "lat": -1.288, "lng": 36.823 }
}

JS 桥接根据 id 解析对应的 Promise。


3. JavaScript ↔ 原生边界

这是两个世界之间实际的"通道"。

JS → 原生:

  • 通过 addJavascriptInterface 实现
  • JS 调用 Android.postMessage(jsonString)

原生 → JS:

  • 通过 evaluateJavascript() 实现
  • 原生调用 JS 回调,如: window.onNativeMessage(jsonString)

关键特性:

  1. 通信几乎总是异步的(因为原生操作需要时间,JS 期望非阻塞行为)。
  2. 只能传递字符串
  3. 需要 JSON 序列化
  4. 在不同线程上运行

4. 原生桥接层(服务端)

该层接收来自 JS 桥接的 JSON 消息,并将其路由到相应的原生模块。 主要职责: - 接收并解析传入的 JSON 消息 - 识别请求的操作 - 执行相应的原生函数 - 将结果/错误转换为 JSON - 向 JS 发送结构化响应: 示例工作流: cameraflow

5. 原生应用层(设备逻辑)

这是实际的 Android 实现层:

  • 摄像头访问
  • 文件系统操作
  • 位置服务
  • 蓝牙通信
  • 权限管理
  • 存储
  • 后台任务

桥接层在这些功能之上提供了一个抽象层,使 JavaScript 可以请求这些功能,而无需了解 Android 的具体实现方式。

为何采用这种架构?

  • 使 Web 应用程序能够访问原生设备功能
  • 允许使用 Web 技术构建 UI
  • 关注点清晰分离
  • 比直接暴露多个原生方法更安全
  • 可扩展性强,新的原生功能易于添加
  • 适用于任何 JS 框架(React、Vue、Angular、纯 JS)