欢迎扫码,加作者微信

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}`);
    });
});
目录

运营需要亿点资金维持,您的支持,是小白龙创作的动力!!!

昵称
留言
赞赏金额
暂无评论,欢迎留下你的评论
暂无评论,欢迎留下你的评论