1. 什么是 Hybrid 架构?
Hybrid(混合)架构是指 结合 Web 技术和 Native(原生)技术 的移动应用开发模式,通常由以下部分组成:
Web 部分:使用 HTML、CSS、JavaScript(或前端框架如 Vue/React)开发的页面,运行在 WebView(如 Android 的
WebView
或 iOS 的WKWebView
)中。Native 部分:使用原生语言(如 Java/Kotlin、Swift/Objective-C)开发的 App 壳,提供底层能力(如摄像头、GPS、文件系统等)。
典型 Hybrid 架构
┌───────────────────┐ │ Native App │ ← 提供 WebView 容器 + 原生能力 ├───────────────────┤ │ WebView │ ← 加载 Web 页面(H5) └───────────────────┘
Hybrid 的优势
跨平台:一套 Web 代码可运行在 iOS/Android。
动态更新:Web 页面可远程更新,无需发版。
开发效率高:前端技术栈开发速度快。
Hybrid 的劣势
性能较低:WebView 渲染性能不如原生。
通信成本:Web 和 Native 需要频繁通信(JS Bridge)。
2、Hybrid 通信方式(Native ↔ H5)
🔁 通信方向
通信方向 | 描述 |
---|---|
H5 → Native | JS 调用 Native 能力(拍照、分享等) |
Native → H5 | 原生通知 JS(登录成功、跳转等) |
📦 通信方案
一、H5 调 Native:
1. URL Scheme 拦截
原理:H5 通过触发特定格式的 URL 请求(如 jsbridge://method?params=xxx
),Native 拦截后解析并执行对应逻辑。
适用场景:简单操作(如跳转页面、关闭 WebView)。
实现:
// H5 调用
function callNativeByURLScheme(method, params) {
const url = `jsbridge://${method}?${JSON.stringify(params)}`;
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = url;
document.body.appendChild(iframe);
setTimeout(() => iframe.remove(), 100);
}
// 调用示例
callNativeByURLScheme('share', { title: 'Hello' });
Native 端拦截:
Android:重写
WebViewClient.shouldOverrideUrlLoading()
。iOS:实现
WKNavigationDelegate.decidePolicyForNavigationAction()
。
2. navite 注入:JavaScript Interface(Android) / WKScriptMessageHandler(iOS)
原理:Native 向 WebView 注入全局对象或方法,H5 直接调用。
适用场景:需要返回值或复杂交互。
Android(@JavascriptInterface)
// Native 注入对象
webView.addJavascriptInterface(new Object() {
@JavascriptInterface
public void showToast(String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}, "NativeBridge");
// H5 调用
window.NativeBridge.showToast('Hello from H5');
iOS(WKScriptMessageHandler)
swift
// Native 注入
let userContentController = WKUserContentController()
userContentController.add(self, name: "nativeBridge")
webView.configuration.userContentController = userContentController
// 实现回调
func userContentController(_ controller: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "nativeBridge" {
print("收到H5消息:", message.body)
}
}
// H5 调用
window.webkit.messageHandlers.nativeBridge.postMessage({ action: "share" });
二、Native 调用 H5 的常见方案
1. WebView 的 evaluateJavascript
/ stringByEvaluatingJavaScript
原理:Native 直接执行 JS 代码字符串。
Android
webView.evaluateJavascript("javascript:window.h5Method('" + data + "')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
// 获取H5返回值
}
});
iOS
// WKWebView
webView.evaluateJavaScript("window.h5Method('\(data)')") { result, error in
print("H5返回值:", result)
}
三、完整双向通信示例
1. 前端封装
class HybridBridge {
// H5 → Native
static callNative(method, params) {
return new Promise((resolve, reject) => {
if (window.NativeBridge?.[method]) { // Android
try {
const result = window.NativeBridge[method](JSON.stringify(params));
resolve(JSON.parse(result));
} catch (err) {
reject(err);
}
} else if (window.webkit?.messageHandlers?.[method]) { // iOS
window.webkit.messageHandlers[method].postMessage(params);
resolve({ status: 'sent' });
} else {
reject(new Error('NativeBridge未注入'));
}
});
}
// Native → H5 回调注册
static onNativeCall(callback) {
window._nativeCallback = callback;
}
}
// 注册供Native调用的函数
window.handleNativeEvent = (data) => {
if (window._nativeCallback) {
window._nativeCallback(data);
}
};
2. Native 封装
Android(Kotlin)
// 注入Bridge
webView.addJavascriptInterface(object {
@JavascriptInterface
fun getLocation(): String {
return "{\"lat\": 39.9, \"lng\": 116.4}"
}
}, "NativeBridge")
// 调用H5
webView.evaluateJavascript("window.handleNativeEvent('Native数据')", null)
iOS(Swift)
// 注入Bridge
userContentController.add(self, name: "getLocation")
// 调用H5
webView.evaluateJavaScript("window.handleNativeEvent('Native数据')")
window.webkit.messageHandlers.login.postMessage({ userId: 123 });
3. 如何优化 Hybrid 通信方案?
Hybrid 的核心瓶颈是 Web 和 Native 的通信效率,以下是优化方案:
(1) 减少通信次数
批量通信:合并多次调用为一次(如 Native 返回 JSON 而非多次回调)。
事件订阅:用
EventEmitter
模式替代频繁的 JS Bridge 调用。
(2) 优化 JS Bridge
使用高性能 Bridge:
Android: 用
@JavascriptInterface
替代prompt
/console.log
通信。iOS: 用
WKScriptMessageHandler
替代UIWebView
的旧方案。
预加载 Bridge:在 WebView 初始化时注入 Bridge 代码,避免运行时延迟。
(3) 数据缓存
本地存储:用
localStorage
或 Native 缓存减少网络请求。预加载数据:Native 提前加载数据并通过 Bridge 注入到 WebView。
(4) 并行化通信
// 传统串行通信(慢)
const result1 = await Native.method1();
const result2 = await Native.method2();
// 优化:并行通信(快)
const [result1, result2] = await Promise.all([
Native.method1(),
Native.method2()
]);
(5) 使用 WebAssembly
将计算密集型任务(如加密、图像处理)交给 WebAssembly,减少 Bridge 调用。
4. 如何提升 Hybrid 页面性能?
(1) WebView 优化
复用 WebView:避免重复创建 WebView,使用池化技术。
预加载 WebView:在后台提前初始化 WebView。
(2) 前端优化
SSR/SSG:用服务端渲染(Next.js/Nuxt.js)提升首屏速度。
代码分割:按需加载 JS/CSS(如 Webpack 的
splitChunks
)。图片优化:使用 WebP 格式、懒加载、CDN 加速。
(3) 通信协议优化
二进制协议:用 Protocol Buffers 替代 JSON 减少数据传输量。
长连接:用 WebSocket 替代 HTTP 短连接。