Uni-App跨端实战:APP的WebView与H5通信全流程解析(03)

前言

在uniapp开发过程中,uniapp编译出的平台的小程序、APP中,都需要使用webview组件进行内嵌H5。

内嵌H5有哪些好处:

  • 通过web-view内嵌,APP和小程序可以直接复用这些H5资源,避免了重复开发。
  • 无需升级原生代码就能展示新的H5内容,支持动态更新功能

当然H5页面也可调用原生API,这就涉及到内嵌H5与webview通信。对于uniapp可以编译出多平台的代码,每个平台的webview通信都会有所差别。

如图所示:

本文主要讲解和实践APP的webview与h5的双向通信。


相关系列文章:

Uni-App跨端实战:微信小程序WebView与H5通信全流程解析(01)

Uni-App跨端实战:支付宝小程序WebView与H5通信全流程解析(02)

Uni-App跨端实战:APP的WebView与H5通信全流程解析(03)

1. 前置工作

因为是uniapp开发的,按照[uni-app webview官方文档]H5可以使用window.postMessage,但经过实践,这个方法并没办法发送数据.

1.1 引入uni.webview

所以我们使用的都是使用uni.webView.postMessage,需要说明的是不管你的H5是uniapp编译、还是非uniapp编译,都需要额外引入一个js(uni.webview.1.5.6.js)才能支持,需要1.5.6版本才支持鸿蒙系统。

特别需要注意的是: 引入的文件提供的全局变量是uni,如果你的H5是uni-app编译出的,会与原有的uni冲突,会导致覆盖掉你引入的js变量。可以直接修改引入的全局变量,例如将其修改为webUni

解决方案:修改全局uni的名称

可以直接在index.html中引入:

html 复制代码
// uni sdk
<script type="text/javascript" src="/static/uni.webview.1.5.6.js"></script>
<script>
  document.addEventListener('UniAppJSBridgeReady', function () {
    window.webUni = webUni.webView
    webUni.getEnv(function (res) {
      console.log('当前环境:' + JSON.stringify(res));
    });
  });
</script>

经过实践,uniapp编译的H5和非uniapp编译的H5用法一致。

2. APP的webview通信概述

uniapp编译出的APP的weiview通信,参考APP的webview组件官方文档

可以用一个图简述下通信的过程:

下面我们具体实践下。

3. APP->H5

从APP发送参数给H5,有两种方式:

  1. 通过url传参数给H5,并且参数需要encodeURIComponent,参数的长度是有限制的,如果需要带过多参数,
  2. 通过getAppWebview获取webview对象,使用evalJS执行函数传递参数,鸿蒙参考

注意:vue2通过this.$scope.$getAppWebview()来获取当前页面的webview对象。vue3通过获取当前页面路由实例,包含$getAppWebview方法。

$getAppWebview这个方法也不是直接获取到webview实例,需要在children中获取,根据官网描述,还需要有个setTimout的延迟。如果我们需要将App的token发送给H5,那么需要在H5的window上挂载一个方法,例如: window.getToken,那么Android和IOS系统发送token给H5的代码。

具体代码如下:

方式一:

js 复制代码
  <web-view :src="url" @message="bindMessage" @load="bindLoad" id="webview"></web-view>

方式二:

js 复制代码
// vue2写法
const currentWebview = this.$scope.$getAppWebview() 
setTimeout(function() {
  wv = currentWebview.children()[0]
  wv.evalJS(`getToken('${token}')`);
}, 1000); //如果是页面初始化调用时,需要延时一下

// vue3写法

const pages = getCurrentPages();
const index = pages.length - 1;

// 获取到当前页面的webView实例
const currentWebview = pages[index].$getAppWebview();
setTimeout(() => {
  // 取到真正的webview
  const webView = currentWebview.children()[0];
  // 通过evalJS执行H5中的getToken方法,并将token作为参数传递
  webView.evalJS(`getToken('${token}')`);
});

// 鸿蒙系统
const webview = uni.createWebviewContext('webview', context);
const token = 'token_xxx';
webview.evalJs(`getToken('${token}')`);

H5接收:

js 复制代码
// 在window上挂载getToken方法,等待被执行,然后获取Token
window.getToken = function(token) {
   // 被App执行后,就可以获取来自App的token
   console.log(token)
}

4. H5->APP

H5发送到APP的参数,使用webUni.postMessage

js 复制代码
// H5发送
webUni.postMessage({
    data: {
      name: 'jack',
      age: 20,
      title: '复制'
    }
 })
// APP接收
@message="bindMessage"

如果H5直接发送数据,APP是实时接收到数据,数据是一个数组,取第一个数据

5. 总结

最后总结一下: APP的webview通信,APP发送到H5需要考虑不用系统获取webview实例的方式,通过执行H5挂载在window对象上的方法传递数据。H5还是通过postMessage发送消息实现。

如果错误,请指正O^O!

相关推荐
用户69371750013843 小时前
Google 正在“收紧侧加载”:陌生 APK 安装或需等待 24 小时
android·前端
蓝帆傲亦3 小时前
Web 前端搜索文字高亮实现方法汇总
前端
用户69371750013843 小时前
Room 3.0:这次不是升级,是重来
android·前端·google
漫随流水4 小时前
旅游推荐系统(view.py)
前端·数据库·python·旅游
踩着两条虫6 小时前
VTJ.PRO 核心架构全公开!从设计稿到代码,揭秘AI智能体如何“听懂人话”
前端·vue.js·ai编程
jzlhll1237 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin
蓝冰凌7 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛8 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉8 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化