乐于分享
好东西不私藏

uni-app WebView 与原生 App 双向通信完整方案

uni-app WebView 与原生 App 双向通信完整方案

一、方案概述

在uni-app项目开发中,WebView组件常用于加载H5页面,实现混合开发模式。原生App(安卓、iOS)与WebView内H5页面的数据交互是混合开发的核心难点,本文系统性梳理App主动向H5传值、H5主动向App传值两种通信方向,详解 plus.webview.evalJSpostMessage 两种核心通信API,结合安卓录音文件回传、tempFilePath文件路径规则、AI语音识别实战场景,提供可直接落地的完整通信方案,同时补充兼容性适配、异常处理等开发注意事项。

二、通信基础概念与核心API说明

2.1 通信方向划分

  • • App → H5:原生端(安卓/iOS)主动向WebView内的H5页面发送数据,适用于App推送状态、设备信息、权限参数等场景。
  • • H5 → App:H5页面主动向原生App发送指令、业务数据,适用于H5触发原生功能(录音、拍照、支付)、页面状态同步等场景。

2.2 核心API简介

2.2.1 plus.webview.evalJS

该API为原生调用H5 JS方法的核心接口,支持App端直接执行H5页面内定义的JS函数,实现主动向H5推送数据,同步执行、响应速度快,适合高频、简单的数据传输。仅支持uni-app打包后的原生环境,H5浏览器环境无法使用。

2.2.2 postMessage

双向通用通信API,分为原生端postMessage和H5端postMessage,采用异步消息推送机制,支持复杂对象数据传输,可跨页面通信。适合非实时、大数据量、复杂结构的数据交互,是通用性最强的通信方式。

三、App → H5 通信实现方案

App向H5传值主流实现方式为 plus.webview.evalJS,原理是原生WebView实例获取H5全局JS方法,主动注入参数执行函数,完成数据推送。

3.1 前置准备

  1. 1. H5页面提前挂载全局接收方法,绑定至window对象,供原生调用,示例:window.receiveDataFromApp
  2. 2. uni-app端获取WebView实例,通过plus.webview.create创建页面或获取当前WebView对象;
  3. 3. 确保通信时机:需等待H5页面DOM加载完成后执行evalJS,避免方法未挂载导致调用失败。

3.2 完整代码实现

3.2.1 H5端代码(接收App数据)

// H5页面全局挂载接收方法,固定方法名供原生调用
window
.receiveDataFromApp = function(params) {
    // params:原生App传递的参数,支持字符串、对象、数组

    console
.log("App传递至H5的数据:", params);
    // 业务逻辑处理:更新页面数据、修改页面状态、弹窗提示等

    if
(params.code === 200) {
        // 处理正常业务数据

    } else {
        // 处理异常回调

    }
}

3.2.2 uni-app原生端代码(推送数据至H5)

// 获取WebView实例
let
 webView = plus.webview.getWebviewById("h5-page");
// 等待页面加载完成,避免执行时机过早

webView.addEventListener("loaded", function() {
    // 调用H5全局方法receiveDataFromApp,传递自定义参数

    webView.evalJS(`
        window.receiveDataFromApp({
            code: 200,
            msg: "原生推送数据成功",
            data: {
                device: "android",
                version: "1.0.0"
            }
        })
    `
);
})

3.3 方案优缺点

  • • 优点:同步调用、响应延迟低、代码简洁、无额外事件监听;
  • • 缺点:依赖全局JS方法挂载、复杂嵌套数据需手动序列化、跨域隔离严格。

四、H5 → App 通信实现方案

H5向原生App传值优先使用 postMessage,该方式无需提前挂载全局方法,通过消息队列异步推送数据,原生端监听message事件即可接收,适配复杂业务场景。

4.1 通信流程

H5触发postMessage发送消息 => 原生WebView监听message事件 => 原生解析数据执行业务逻辑 => 原生可通过evalJS回调结果至H5。

4.2 完整代码实现

4.2.1 H5端代码(发送数据至App)

// H5主动向原生App发送数据
function
 sendDataToApp() {
    // postMessage支持对象、数组、字符串等格式数据

    window
.plus.webview.currentWebview().postMessage({
        type
: "h5-to-app",
        operate
: "startRecord",
        content
: "H5触发原生录音功能",
        time
: new Date().getTime()
    })
}

4.2.2 uni-app原生端代码(监听接收H5数据)

let webView = plus.webview.getWebviewById("h5-page");
// 监听H5发送的message消息

webView.addEventListener("message", function(event) {
    // event.data为H5传递的原始数据

    let
 h5Data = event.data;
    console
.log("H5传递至App的数据:", h5Data);
    // 根据type区分业务逻辑

    switch
(h5Data.operate) {
        case
 "startRecord":
            // 触发原生录音逻辑

            startAndroidRecord
();
            break
;
        case
 "stopRecord":
            // 停止录音

            stopAndroidRecord
();
            break
;
        default
:
            break
;
    }
})

4.3 postMessage补充说明

  1. 1. 数据传输限制:不支持函数、DOM节点等特殊类型数据,传输前需过滤特殊格式;
  2. 2. 执行环境:仅plus环境可用,需判断 window.plus 是否存在,避免浏览器环境报错;
  3. 3. 回调方式:原生处理完成后,通过evalJS调用H5回调函数返回执行结果。

五、安卓录音回传实战(核心业务场景)

录音是混合开发高频场景,本文基于上述双向通信方案,实现H5触发原生录音、安卓原生录音、音频文件回传H5的完整流程,同时解析tempFilePath临时文件路径规则。

5.1 业务流程梳理

  1. 1. H5通过postMessage向App发送录音指令;
  2. 2. 安卓原生调用系统录音API,生成音频临时文件;
  3. 3. 原生获取音频tempFilePath临时路径;
  4. 4. 通过evalJS将文件路径、音频时长等数据回传给H5;
  5. 5. H5基于路径实现音频预览、上传、AI语音识别。

5.2 安卓原生录音代码实现

// 原生录音方法
function
 startAndroidRecord() {
    // 申请录音权限

    plus.android.requestPermissions(["android.permission.RECORD_AUDIO"], function(res) {
        if
(res.granted.length > 0) {
            // 创建录音实例

            let
 audioRecorder = plus.audio.createRecorder();
            audioRecorder.start();
            // 录音结束回调

            audioRecorder.onstopped = function(path) {
                // path为音频临时文件路径 tempFilePath

                let
 tempFilePath = path;
                // 将音频路径回传给H5

                webView.evalJS(`
                    window.receiveDataFromApp({
                        code: 200,
                        type: "record-end",
                        filePath: "${tempFilePath}",
                        duration: ${audioRecorder.getDuration()}
                    })
                `
);
            }
        } else {
            // 权限拒绝回调

            webView.evalJS(`window.receiveDataFromApp({code: 403, msg: "录音权限拒绝"})`);
        }
    })
}

5.3 tempFilePath路径详解

5.3.1 路径定义

tempFilePath是uni-app原生生成的临时文件路径,属于应用私有目录,仅当前App可访问,无需手动申请文件读写权限,录音、拍照、截图生成的文件均默认存储至该目录。

5.3.2 安卓路径格式

// 安卓临时文件路径示例
/_doc/uniapp_temp/record/20260516/record_123456.amr

5.3.3 路径使用注意事项

  • • 生命周期:临时文件在App重启后可能被系统清理,重要音频需手动保存至持久目录;
  • • H5访问权限:WebView默认允许访问应用私有临时路径,无需配置白名单;
  • • 格式转换:安卓原生录音默认生成amr格式,H5播放器兼容性较差,建议转码为mp3格式。

六、AI语音识别集成方案

基于安卓录音回传的音频临时路径,结合第三方AI语音识别接口,实现音频转文字功能,适配H5+原生混合开发场景,提供两种落地方式。

6.1 方案一:原生解析+AI识别(推荐)

6.1.1 流程

安卓录音生成tempFilePath => 原生读取音频文件 => 调用AI语音识别SDK => 识别完成通过evalJS回传文本至H5。

6.1.2 核心代码片段

// 录音结束后执行AI识别
audioRecorder.onstopped = function(path) {
    // 调用原生集成的AI语音识别接口

    aiVoiceRecognition
(path).then(res => {
        // 识别结果回传给H5

        webView.evalJS(`
            window.receiveDataFromApp({
                code: 200,
                type: "ai-text",
                filePath: "${path}",
                text: "${res.text}",
                confidence: ${res.confidence}
            })
        `
);
    })
}

6.2 方案二:H5解析+接口识别

  1. 1. 原生将tempFilePath传递至H5;
  2. 2. H5通过plus.io读取临时音频文件,转换为base64格式;
  3. 3. 调用云端AI语音识别API,上传base64音频数据;
  4. 4. 接收识别文本,完成业务渲染。

6.3 AI识别优化注意事项

  • • 音频压缩:录音文件过大将导致识别延迟,安卓端需配置音频采样率、比特率,压缩文件体积;
  • • 异常处理:增加音频损坏、网络超时、识别失败的异常回调,兼容低版本安卓机型;
  • • 权限配置:AI识别需网络权限,打包时需在manifest.json配置网络访问权限。

七、两种通信方式对比与选型标准

通信方式
通信方向
执行方式
适用场景
优缺点
plus.webview.evalJS
App → H5
同步执行
实时简单数据推送、结果回调
响应快、依赖全局方法、不适合复杂数据
postMessage
双向通信
异步执行
H5触发原生功能、复杂数据传输
通用性强、无挂载依赖、存在轻微延迟

八、常见问题与兼容解决方案

8.1 方法调用失败(找不到H5全局方法)

问题原因:evalJS执行时机早于H5页面加载完成;解决方案:绑定WebView的loaded监听事件,页面加载完成后再执行通信方法。

8.2 安卓tempFilePath路径无法访问

问题原因:应用后台重启、临时文件被清理;解决方案:重要音频文件通过plus.io.moveTo方法迁移至持久目录。

8.3 postMessage数据丢失

问题原因:传输数据包含特殊格式、循环引用;解决方案:传输前使用JSON序列化数据,过滤函数、DOM节点。

8.4 低版本安卓录音兼容性问题

问题原因:安卓6.0以下无动态权限;解决方案:manifest.json配置最低兼容版本,静态声明录音权限。

九、总结

本文完整实现uni-app WebView与原生App双向通信方案,明确 evalJS用于App主动推送数据、postMessage用于H5主动触发原生功能 的核心选型逻辑。结合安卓录音场景,详解tempFilePath临时文件路径规则,搭配AI语音识别完成业务闭环。该方案适配绝大多数混合开发场景,代码可直接复用,同时通过权限处理、时机优化、异常兼容,解决安卓机型适配、文件访问、数据传输等常见问题,是uni-app混合开发WebView通信的通用落地方案。