
App中内嵌H5页面实现通信
2025-06-12 20:13:30
2025-06-14 20:41:24
在App中内嵌H5页面并实现通信是常见的混合开发场景,主要通过JavaScript与原生代码交互实现。以下是主流平台的核心实现方案:
一、通信原理
H5 → App
H5调用原生能力(如相机、存储等)
App → H5
原生触发H5页面更新(如传递用户信息)
双向通信
通过约定协议实现数据交换
二、Android实现方案
方法1:JavaScriptInterface(官方推荐)
language
// 1. 定义接口类
public class JsBridge {
@JavascriptInterface
public void showToast(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
}
// 2. 注册到WebView
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsBridge(), "AndroidBridge");
// 3. H5调用
window.AndroidBridge.showToast("Hello from H5!");
方法2:URL Scheme拦截
language
// H5触发自定义协议
location.href = "myapp://action?param1=value1";
language
// Android拦截请求
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("myapp://")) {
// 解析并执行原生操作
return true; // 拦截请求
}
return false;
}
});
三、iOS实现方案
方法1:WKScriptMessageHandler(推荐)
language
// 1. 注册消息处理器
let contentController = WKUserContentController()
contentController.add(self, name: "iosBridge")
// 2. H5发送消息
window.webkit.messageHandlers.iosBridge.postMessage({data: "Hello"})
// 3. 原生处理消息
func userContentController(_ controller: WKUserContentController,
didReceive message: WKScriptMessage) {
if message.name == "iosBridge",
let data = message.body as? [String: Any] {
print("Received:", data["data"] ?? "")
}
}
方法2:JavaScriptCore(UIWebView旧方案)
language
// 1. 获取JSContext
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 2. 注入对象
context[@"nativeBridge"] = ^(NSString *msg) {
NSLog(@"H5消息: %@", msg);
};
// H5调用
nativeBridge("Hello iOS!");
四、通用增强方案
1. 封装JS Bridge库
language
// 统一调用入口
function callNative(method, params, callback) {
// Android
if (window.AndroidBridge) {
window.AndroidBridge[method](JSON.stringify(params));
}
// iOS
else if (window.webkit?.messageHandlers?.iosBridge) {
window.webkit.messageHandlers.iosBridge.postMessage({
func: method,
data: params
});
}
}
2. 安全加固
language
通信双方验证来源(防止恶意页面调用)
iOS启用requiresUserActionForMediaPlayback
Android禁用setAllowUniversalAccessFromFileURLs
五、完整通信流程示例

六、调试技巧
Android
使用Chrome chrome://inspect 调试WebView
iOS
Safari开发者工具调试WebView
抓包工具
使用Charles分析通信数据
注意事项
异步处理:所有原生操作需异步返回结果
版本兼容:Android 4.2+ 必须使用@JavascriptInterface
参数类型:复杂数据使用JSON序列化
内存泄漏:iOS的WKScriptMessageHandler需及时移除
建议使用成熟开源库简化开发:
Android:JockeyJS
iOS:WebViewJavascriptBridge
通过标准化通信协议,可实现H5与App的高效、安全交互,同时保持H5的动态更新能力。
H5 端通用实现(JockeyJS + WebViewJavascriptBridge)
1. 初始化 Bridge
language
// 兼容 Android 和 iOS 的初始化函数
function initBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge);
}
if (window.Jockey) { // Android 的 JockeyJS
callback({
callHandler: Jockey.trigger,
registerHandler: Jockey.on
});
} else { // iOS 的 WebViewJavascriptBridge
document.addEventListener('WebViewJavascriptBridgeReady', () => {
callback(window.WebViewJavascriptBridge);
}, false);
}
}
initBridge(function(bridge) {
// 注册 JS 处理器供原生调用
bridge.registerHandler("changeTheme", function(data, responseCallback) {
document.body.className = data.theme;
responseCallback("Theme applied!"); // 通知原生完成
});
// 调用原生方法(如获取用户信息)
bridge.callHandler("getUserInfo", { userId: "1001" }, function(response) {
console.log("用户数据:", response.name, response.email);
});
});
2. 主动发送消息给原生
language
// H5 触发扫码功能
document.getElementById("scan-btn").addEventListener("click", () => {
bridge.callHandler("scanQRCode", "qrcode", (result) => {
alert(`扫码结果: ${result.code}`);
});
});
目录