HarmonyOS WebView
HarmonyOS WebView
- Web组件提供基础的前端页面加载的能力,包括加载网络页面、本地页面、html格式文本数据。
- Web组件提供丰富的页面交互的方式,包括:设置前端页面深色模式,新窗口中加载页面,位置权限管理,Cookie管理,应用侧使用前端页面JavaScript等能力。
注意:使用 webview 一定要去开启网络权限,否则页面将无法加载
1.创建一个简单的 webview 页面
1.1 app端 创建 webview 页面
// 1. 引入依赖
import { webview } from '@kit.ArkWeb';// 2. 创建webview控制器
@State message: string = 'webview page'
private controller: WebviewController = new webview.WebviewController()build () {Column ({ space: 15 }) {Text( this.message ).fontSize( 50 ).fontWeight( FontWeight.Bold )// 2. 利用 Web 组件引入对应的 Web端 内容Web({ src: '自己本地随便启动一个项目地址', controller: this.controller }).width('80%').height(400).backgroundColor('#11dd00')}.height( '100%' ).width( '100%' )
}
2.app端 输出 h5 的日志
- 正常情况下我们开发会有很多日志输出,开发过webview的同学都知道,h5的日志不太好看,除非使用Vconsole插件
- 鸿蒙对这个情况做的比较好,可以直接在app端的日志输出h5的日志
- 使用webvivew属性 OnConsole 监听h5的console.log输出,并在控制台输出日志
Web({ src: '自己本地随便启动一个项目地址', controller: this.controller }).width('80%').height(400).backgroundColor('#11dd00').border({width: 1,radius: 5,style: BorderStyle.Solid}).onConsole((event) => {console.log('wuwuwu h5 打印的日志 => ', event?.message.getMessage())return true})
3.h5 和 app端 方法调用(数据传递)
- 方法1:在鸿蒙中 h5 和 app端的交互是通过 window 来进行的
- h5 把方法挂载到 window 对象上,app端 可以通过固定方法调用
- app端 也可以通过固定api 把方法挂载到 window 对象上让 h5 调用。
- 如果要做数据传递,在方法中加上返参或者回调即可
- 方法2:可以通过双向数据通道进行数据传递
- 实际上就是通过 postMessage
3.1 app端 调用 h5 的方法
3.1.1 h5 挂载方法到 window 对象上
// 在 h5 中,监听window.onload事件,挂载方法 testA 到 window 对象上
window.onload = () => {window.testA = () => {console.log('testFn 方法被调用')}
}
3.1.2 app端 调用 h5 的方法
// app端 创建一个按钮,通过按钮触发 h5 中的 testA 方法
Button('调用h5按钮').onClick(() => {// 使用 webview 控制器中的方法 runJavaScript 调用 h5 中的 testA 方法this.controller.runJavaScript('testA()')console.log('wuwuwu => 1. 调用 testFn 方法')})
3.2 h5 调用 app端 的方法
3.2.1 app端 挂载方法到 window 对象上
- app端 需要创建一个事件对象
- 通过固定api挂载到 window对象上
- 根据api可以分为两种方式
3.2.1.1 创建事件对象
// 通过 class 创建一个全局公共类,里面包含一个方法 testB
class ToWebObject {constructor() {}public testB() {console.log('wuwuwu 我是 App端 的打印信息 => App端 的 testB 函数被调用了')}
}
3.2.1.2 使用 web 属性 javaScriptProxy 挂载方法到 window 对象上
// app端
// 创建要挂载的内容
@State sendObject: ToWebObject = new ToWebObject()Web({ src: '自己本地随便启动一个项目地址', controller: this.controller }).width('80%').height(400).backgroundColor('#11dd00').border({width: 1,radius: 5,style: BorderStyle.Solid}).onConsole((event) => {console.log('wuwuwu h5 打印的日志 => ', event?.message.getMessage())return true}).javaScriptProxy({// 挂载的事件对象object: this.sendObject,// 挂载到 window 对象上的属性名name: 'wuwuwu',// 注册的方法名,只有在这个数据中的方法 h5 才可以调用// 比如 object 中有两个方法 testA 和 testB,h5 只能调用 testB 方法methodList: ['testB'],controller: this.controller})
3.2.1.3 使用 webview 控制器的方法 registerJavaScriptProxy 挂载方法到 window 对象上,使用此方法后必须调用 refresh,方法才能生效
// app端
// 创建要挂载的内容
@State sendObject: ToWebObject = new ToWebObject()
// 控制器
private controller: WebviewController = new webview.WebviewController()// web 组件
Web({ src: '自己本地随便启动一个项目地址', controller: this.controller }).width('80%').height(400).backgroundColor('#11dd00').border({width: 1,radius: 5,style: BorderStyle.Solid}).onConsole((event) => {console.log('wuwuwu h5 打印的日志 => ', event?.message.getMessage())return true})// 新建俩按钮用来挂载事件
Row() {Button('注册一些事件').onClick(() => {this.controller.registerJavaScriptProxy(this.sendObject,'wuwuwu',['testB'],)})Button('刷新一下激活事件').onClick(() => {this.controller.refresh()})
}
3.2.1.4 使用 webview 控制器的方法 registerJavaScriptProxy 挂载方法到 window 对象上,可以在声明周期 onControllerAttached 上调用该方法,此时 h5 还未加载
Web({ src: '自己本地随便启动一个项目地址', controller: this.controller }).width('80%').height(400).backgroundColor('#11dd00').border({width: 1,radius: 5,style: BorderStyle.Solid}).onConsole((event) => {console.log('wuwuwu h5 打印的日志 => ', event?.message.getMessage())return true}).onControllerAttached(() => {this.controller.registerJavaScriptProxy(this.sendObject,'wuwuwu',['testB'],)// 这块有个问题 ,在这个声明周期中调用onControllerAttached,在不调用refresh的情况下 h5 可以正常调用testB// 官方文档中只是说 onControllerAttached 必须要调用 refresh,才能生效// 这里不知道是有真的问题 或者是 官方文档没有跟新这部分内容// 我猜测是因为这个生命周期的时候 h5 还没有加载导致,,相当于 refresh 的作用this.controller.refresh()})
3.2.1.5 h5 调用方法,不管 app端 咋么调用,h5 都通过 window 对象来调用
// h5
// 直接调用 window 方法就行
// window.挂载时的name.要调用的方法名
window.wuwuwu.testB()
3.3 建立 app端 和 h5 双向数据通道
-
1.创建双向数据通道接口
- 使用的 API
- webview 控制器方法 createWebMessagePorts()
- 返回值:
- 是一个数组, 数组内有两个接口 [ 接口1, 接口2 ]
- [0] : 提供给 h5端 使用的, 需要传递给 h5端, h5端 使用这个接口去监听 App端 发来的消息, 同时也是使用这个接口向 App 端发送消息
- [1] : 提供给 App端 使用的, App端 使用这个接口去监听 h5端 发来的消息, 同时也是使用这个接口向 h5端 发送消息
- 使用的 API
-
2.把属于 h5端 的接口传递过去
- 注意: 此时不是 App端 和 h5端 建立好通道传递
- 而是先把建立通道的 “工具” 传递过去
- 所以, 此时是 App端 给 window 发送一个消息( 而不是和 h5端 建立通道连接 )
- 注意: 此时不是 App端 和 h5端 建立好通道传递
-
3.建立通道
- 使用 webview 控制器方法 postMessage 把 “接口工具” 发过去
- App端 和 h5端 都利用 “接口工具” 去建立双向连接通道
3.3.1 创建创建双向数据通道接口,并完成事件监听
- 双向通道数据接口通过 webview 控制器方法 createWebMessagePorts() 创建
// ---------- app端
// 变量private controller: WebviewController = new webview.WebviewController()
private posts: webview.WebMessagePort[] = []
private appPort: webview.WebMessagePort = Object()registerPortMessage() {this.posts = this.controller.createWebMessagePorts()// this.posts === [ h5端使用的接口, App端使用的接口 ]this.appPort = this.posts[1]// 把 h5 使用的接口传递给 h5this.controller.postMessage('__init__port__', [this.posts[0]], '*')// 监听 h5 发送的消息this.posts[1].onMessageEvent((event) => {this.messageEventHandle(event)})
}messageEventHandle(event: webview.WebMessage) {const resultInfo = JSON.parse(event as string) as ResultInfoTypeif (resultInfo.message === '__awu__') {console.log('wuwuwu app 端 接收到数据了', resultInfo.info.username, resultInfo.info.password, resultInfo.info.msg)// 接收到数据之后,告诉 h5 我接收到了数据this.appPort.postMessageEvent(JSON.stringify({message: '__awu__',info: '我接收到数据了'}))}
}// ----------h5端
// 变量
const count = ref(0)
const webPort = ref()// 监听 window 消息
window.addEventListener('message',(event)=>{// data 需要和 app端 发送消息的一致if(event.data === '__init__port__' && event.ports[0] !== null){// 表示发来的消息是 __init__port__// 并且携带了属于 h5端 的那个接口webPort.value = event.ports[0]// 至此, 你需要给 App端 发送消息的时候, 就可以使用 webPort 发送消息// 利用接口工具建立连接通道// 利用接口工具建立连接通道, 利用的事 App端 发送过来的接口工具webPort.value.onmessage = (event:any) => {// 接收到 App端 发送的消息 事件处理console.log('messageEventHandler',event.data)}}
})
3.3.2 发送消息
- 发送消息通过 通道 发送
// app端
Button('发送点信息').onClick(() => {// 1. 发送数据// this.appPort.postMessageEvent(JSON.stringify({// message: '__awu__',// info: '按钮发送的数据'// }))// 2. 发送数据this.appPort.postMessageEvent('按钮发送的数据')})// h5 端
const sendMessage = ()=>{webPort.value.postMessage(JSON.stringify({message: '__awu__',info: { username: 'admin', password: '1234567',msg:`这是发送的第${count.value}消息` }}))count.value++
}
相关文章:
HarmonyOS WebView
HarmonyOS WebView Web组件提供基础的前端页面加载的能力,包括加载网络页面、本地页面、html格式文本数据。Web组件提供丰富的页面交互的方式,包括:设置前端页面深色模式,新窗口中加载页面,位置权限管理,C…...
解决elementUI表格里嵌套输入框,检验时错误信息被遮挡
1.表格 自定义错误信息显示div <el-form-item label"租赁价格" prop"supplierId"><el-table-column prop"salePrice" label"销售价" align"center"><template slot-scope"scope"><el-form-…...

Unity读取Android外部文件
最近近到个小需求,需要读Android件夹中的图片.在这里做一个记录. 首先读写部分,这里以图片为例子: 一读写部分 写入部分: 需要注意的是因为只有这个地址支持外部读写,所以这里用到的地址都以 :Application.persistentDataPath为地址起始. private Texture2D __CaptureCamera…...
【5.3 python中的元组】
5.3 python中的元组 Python中的元组(Tuple)是一种用于存储多个项目(可以是不同类型)的序列数据结构,但它与列表(List)不同,主要区别在于元组是不可变的(immutable&#…...

Debezium报错处理系列之第116篇:Caused by: java.lang.NumberFormatException: null
Debezium报错处理系列之第116篇:Caused by: java.lang.NumberFormatException: null 一、完整报错二、错误原因三、解决方法Debezium从入门到精通系列之:研究Debezium技术遇到的各种错误解决方法汇总: Debezium从入门到精通系列之:百篇系列文章汇总之研究Debezium技术遇到的…...

【启明智显技术分享】工业级HMI芯片Model3C/Model3A开发过程中问题记录笔记二
一、Model3C/Model3A芯片介绍 Model3C/Model3A是启明智显针对工业、行业以及车载产品市场推出的一款高性能、低成本的工业级HMI(Human-Machine Interface,人机界面)芯片。两颗芯片硬件PIN TO PIN;区别在于内置的PSRAM大小不同。该…...

Python 函数返回yield还是return?这是个问题
如果你刚入门 Python,你可能之前没有遇到过yield。虽然它看起来很奇怪,但它是你编码工具库中的一个重要工具。在成为 Python 大师的道路上,你必须掌握它。 返回列表的函数 假设有一个函数,它可以一次性生成一系列值,…...
Linux系统性能调优
Linux系统性能调优是一个复杂而细致的过程,涉及硬件、软件、内核参数、进程管理等多个方面。以下将从多个角度详细介绍Linux系统性能调优的技巧,旨在帮助用户提升系统的运行效率和稳定性。 一、硬件层面的调优 内存升级: 增加物理内存可以减…...

PHPStorm 环境配置与应用详解
大家好,我是程序员小羊! 前言: PHPStorm 是 JetBrains 出品的一款专业 PHP 集成开发环境(IDE),凭借其智能的代码补全、调试功能、深度框架支持和前端开发工具,为用户提供了丰富的功能和工具…...

前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载
前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载 各种文本文件预览(pdf, xlsx, docx, cpp, java, sql, py, vue, html, js, json, css, xml, rust, md, txt, log, fa, fasta, tsv, csv 等各种文本文件) 其中 除p…...
【Qt】QPluginLoader 类学习
文章目录 一、简介二、常用方法2.1 构造函数2.2 动态加载方法——load()2.3 检查是否加载成功——isLoaded()2.4 访问插件中的根组件——instance()2.5 卸载插件——unload() 一、简介 QPluginLoader 类在运行时加载插件。 QPluginLoader 提供对Qt插件的访问。Qt插件存储在共享…...
DataGear 企业版 1.2.0 发布,数据可视化分析平台
DataGear 企业版 1.2.0 已发布,欢迎体验! http://datagear.tech/pro/ 企业版 1.2.0 修复严重漏洞,新增文件源管理模块,新增JWT统一登录支持,MQTT数据集主题支持通配符,具体更新内容如下: 新增…...

为啥https比http慢
Https有ssl的握手 HTTP没有 HTTPS TCP 和HTTP 的TCP 时间差不是很大 HTTPS请求中,ssl所占的时间比例是请求时间总和93.37%, HTTPS请求中,ssl的请求会是tcp请求的14倍,而HTTP中没有这个问题 建议:对安全要求不是很高的,不要使用https请求 图例...

软件测试需要具备的基础知识【功能测试】---后端知识(三)
您好,我是程序员小羊! 前言 为了更好的学习软件测试的相关技能,需要具备一定的基础知识。需要学习的基础知识包括: 1、计算机基础 2、前端知识 3、后端知识 4、软件测试理论 后期分四篇文章进行编写,这是第三篇 …...
详解 Redis 队列 实现
Redis 是一个高性能的键值存储系统,它的多种数据结构使其能够以不同方式实现队列,包括普通队列、延时队列和异步队列的介绍和示例。 介绍 Redis 的 List 数据结构可以用来实现普通的队列。 生产者使用 LPUSH 或 RPUSH 命令将消息添加到列表的头部或尾部…...

分析SQL的count(*)并优化
最近优化过几个慢查询接口的性能,总结了一些心得体会拿出来跟大家一起分享一下,希望对你会有所帮助。 我们使用的数据库是Mysql8,使用的存储引擎是Innodb。这次优化除了优化索引之外,更多的是在优化count(*)。 通常情况下&#…...

Java学习日记(day18)
一、软件的结构 C/S (Client - Server 客户端-服务器端) 典型应用:QQ软件 ,飞秋,印象笔记。 特点: 必须下载特定的客户端程序。服务器端升级,客户端升级。 B/S (Broswer -Server 浏览器端- 服务器端&a…...
Oracle(61)什么是外部表(External Table)?
外部表(External Table)是Oracle数据库中的一种特殊表类型,用于访问存储在外部文件系统中的数据,而不需要将数据实际加载到数据库内部。外部表的主要优势在于允许数据库用户在不移动或复制数据的情况下,直接查询和处理…...

物联网HMI/网关搭载ARM+CODESYS实现软PLC+HMI一体化
物联网HMI/网关搭载CODESYS实现软PLCHMI一体化 硬件:ARM平台,支持STM32/全志T3/RK3568/树莓派等平台 软件:CODESYS V3.5、JMobile Studio CODESYS是一款功能强大的PLC软件编程工具,它支持IEC61131-3标准IL、ST、FBD、LD、CFC、…...
Java中Stream流
Java中Stream流 Stream 使用flatMap处理嵌套集合: 有一个对象列表,每个对象又包含一个列表,可以使用flatMap来“展平”这个结构。 List<List<String>> listOfLists Arrays.asList(Arrays.asList("a", "b"),Arrays.a…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...