HarmonyOS Web组件(二)
1. HarmonyOS Web组件
官方文档
1.1. 混合开发的背景和好处
混合开发(Hybrid Development)是一种结合原生应用和Web应用的开发模式,旨在同时利用两者的优势。随着移动应用需求的多样化和复杂化,单一的开发方式往往难以满足所有需求。混合开发提供了一种灵活、高效的解决方案,特别是在以下方面具有显著的优势:
(1)跨平台兼容:混合开发允许开发者编写一次代码,并在多个平台(如Android、iOS、HarmonyOS等)上运行。这大大减少了开发和维护成本。
(2)快速迭代:Web技术(如HTML、CSS、JavaScript)的快速开发和部署能力,使得混合应用可以更快地进行迭代和更新。
(3)丰富的Web生态:借助丰富的Web生态系统,开发者可以利用大量现有的Web库和框架,快速实现复杂功能。
(4)原生性能:通过将关键功能部分使用原生代码实现,混合应用可以在保证性能的同时,享受Web开发的灵活性。
1.2.混合开发应用的结构
为了更好地理解混合开发的概念,以下是一张示意图,展示了混合开发架构中原生代码与Web代码的结合。
(图中展示了混合开发应用的结构,其中包括:
(1)原生层 Native Layer:包括操作系统(如HarmonyOS)、设备硬件和原生API,提供高性能和底层功能支持。
(2)Web层 Web Layer:包括HTML、CSS、JavaScript等Web技术,负责应用的界面和逻辑部分。
(3)桥接层 Bridge Layer:连接原生层和Web层,允许两者之间的数据和功能交互。
通过这种架构,开发者可以在Web层快速构建界面和业务逻辑,同时利用原生层提供的高性能和丰富功能,实现混合开发的最佳效果。
在HarmonyOS NEXT Developer Beta1版本中,ArkTS 提供了强大的混合开发能力,允许开发者在应用中嵌入 Web 组件,利用 Web 技术构建应用的一部分。接下来,我将介绍如何在 ArkTS 中使用 Web 组件。
1.3. ArkTS Web 组件教程
1.3.1. 语法说明
在 ArkTS 中,混合开发主要通过 Web 组件和 WebView API 来实现。通过这些工具,可以加载和显示网页内容,进行页面控制和数据交互。
官方文档
1.3.1.1. 基本语法
Web 组件用于在界面中嵌入一个网页浏览器。它的常用属性包括:
src:指定要加载的网页资源地址。
controller:webview控制器。
src: ResourceStr = 'https://m.jd.com'
Web({ src: this.src, controller: this.controller })
注意:访问在线网页时需添加网络权限:ohos.permission.INTERNET
1.3.1.2 . 事件处理
Web 组件支持多种事件,如:
(1)onPageBegin:页面开始加载时触发。
(2)onPageEnd:页面加载完成时触发。
(3)onErrorReceive:页面加载出错时触发。
(4)onTitleReceive:网页document标题更改时触发该回调。
(5)onProgressChange:网页加载进度变化时触发该回调。
(6)onRefreshAccessedHistory:加载网页页面完成时触发该回调,用于应用更新其访问的历史链接。
(7)onAppear:组件挂载显示后触发此回调(通用事件)。
Web({ src: this.src, controller: this.controller }).onProgressChange((data) => {}).onPageBegin(() => {}).onPageEnd(() => {}).onErrorReceive((e) => {}).onTitleReceive((data) => {}).onRefreshAccessedHistory(() => {}).onAppear(() => {})
1.3.1.3 . WebView API
WebView API 提供了一组方法和属性,用于更细粒度地控制 Web 组件,如加载URL、执行JavaScript代码等。
import { webview } from '@kit.ArkWeb'// 1. 创建 WebView 实例
controller = new webview.WebviewController()
// 2. 调用WebView 实例 api 进行控制
run() {// 动态加载页面this.controller.loadUrl('url')// 注入 js 对象this.controller.registerJavaScriptProxy// ...
}
Web({ src: this.src, controller: this.controller })
1.3. 实战案例
1.3.1. 新建工程
主要目录结构:
|-- entry
| |-- src
| | |-- main
| | | |-- ets
| | | | |-- pages
| | | | | |-- Index.ets(案例代码)
|-- module.json5
1.3.2. 配置权限
在 module.json5 中配置网络权限:
{"module": {"name": "entry","type": "entry","description": "$string:module_desc",// ..."requestPermissions": [{ "name": "ohos.permission.INTERNET" }],"deliveryWithInstall": true,"installationFree": false,"pages": "$profile:main_pages","abilities": [// ...],"extensionAbilities": [// ...]}
}
1.3.3. 加载页面
在 Index.ets 文件中,使用 Web 组件和 WebView API,加载web页面:
@Entry
@Component
struct WebPage {// 1. web 组件基本使用src: ResourceStr = 'https://m.jd.com'// webview控制器controller = new webview.WebviewController()build() {Navigation() {Web({ src: this.src, controller: this.controller })}.title('混合开发').titleMode(NavigationTitleMode.Mini)}
}
1.3.4. 页面标题
获取当前加载网页标题,进行动态展示
// ...@State// 当前网页的标题title: string = ''build() {Navigation() {Web({ src: this.src, controller: this.controller }).onTitleReceive((data) => {this.title = data?.title || '--'})}.title(this.title).titleMode(NavigationTitleMode.Mini)}
1.3.5. 页面进度
获取页面进度数据,添加进度条效果:
(1)第一步:定义状态,存储加载中和进度数据
// 当前访问页面历史记录索引historyCurrIndex: number = 0
(2)第二步:添加事件获取历史记录
// ...
.onRefreshAccessedHistory(() => {
// == 网页加载完成可访问页面历史记录 ==
// 获取当前Webview的页面历史记录列表
const history = this.controller.getBackForwardEntries()
// 当前页面历史记录索引
this.historyCurrIndex = history.currentIndex
// 历史记录索引的数量,最多保存50条,超过时起始记录会被覆盖
console.log('mgx', history.size)
})
(3)第三步:在原生返回钩子函数中控制逻辑
onBackPress() {// 在web容器中, 当前页面之前还有页面, 则容器内返回上一页if (this.historyCurrIndex > 0) {this.controller.backward()} else {// 返回原生页面router.back()}// 自定义返回逻辑return true}
1.3.6. 在页面标题中添加菜单图标,点击刷新页面。
(1)第一步:给Navigation组件右侧添加菜单(图标随便)
build() {Navigation() {// ...}
.title(this.title)
.titleMode(NavigationTitleMode.Mini)
.menus(this.titleMenus)
}
(2)第二步:定义菜单 Builder 绑定事件控制刷新
@BuildertitleMenus() {Row() {Image($r('app.media.startIcon')).width(18).aspectRatio(1).margin({ right: 10 }).onClick(() => {// 刷新网页this.controller.refresh()})}.width(50).height('100%').justifyContent(FlexAlign.End).alignItems(VerticalAlign.Center)}
1.3.7. JSBridge代理
接下来,进入重点环节,我们来学习实操下如何向 Web 容器的网页中注入 JS 对象,给网页提供原生的能力支持,例如: 选择相册、拍照、传感器等底层能力。
核心依赖webview 提供的registerJavaScriptProxy api,提供了应用与Web组件加载的网页之间强大的交互能力。注入JavaScript对象到window对象中,并在window对象中调用该对象的方法。
官方参考文档
(1)第一步:定义注入 JS 的类型
示例注入了两个函数:
test 方法,获取网页调用后传参
select 方法,选择原生相册,获取选择图片结果显示到网页中
interface InjectJs {// 测试方法test: (a: string) => void// 选择相册select: () => Promise<string>
}type InjectKeys = keyof InjectJs
(2)第二步:定义注入的方法和逻辑
// 2. JSBridge代理webInject() {this.controller.registerJavaScriptProxy({// 参数 1:注入应用侧JavaScript对象// 参数 2:注入对象的名称,与window中调用的对象名一致// 参数 3:注入后window对象可以通过此名字访问应用侧JavaScript对象test: (a) => {AlertDialog.show({message: `网页传参:${a}`})},select: async () => {// 1. 打开相册选择图片const photoSelectOptions = new picker.PhotoSelectOptions()photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;photoSelectOptions.maxSelectNumber = 1;const photoPicker = new picker.PhotoViewPicker();const res = await photoPicker.select(photoSelectOptions)// 2. 文件操作// 2.1 获取照片的uri地址const uri = res.photoUris[0]// 2.2 根据uri同步打开文件const file = fs.openSync(uri)// 2.3 同步获取文件的详细信息const stat = fs.statSync(file.fd)// 2.4 创建缓冲区存储读取的文件流const buffer = new ArrayBuffer(stat.size)// 2.5 开始同步读取文件流到缓冲区fs.readSync(file.fd, buffer)// 2.6 关闭文件流fs.closeSync(file)// 3. 转成base64编码的字符串const helper = new util.Base64Helper()const str = helper.encodeToStringSync(new Uint8Array(buffer))return 'data:image/png;base64,' + str}} as InjectJs,'mg',['test','select',] as InjectKeys[])}
(3)第三步:在通用事件onAppear 执行注入
Web({ src: this.src, controller: this.controller })
// ...
.onAppear(() => {
// JSBridge代理注入
this.webInject()
})
(4)第四步:本地创建网页加载
这里使用的是原生 js 开发网页端,实际开发中可选择 vue 、 react 、 uni-app 等框架开发,效率更高。
目录:entry/src/main/resources/rawfile/index.html
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>混合开发</title><style>* {margin: 0;padding: 0;}ul li {padding: 10px;}
</style>
</head><body>
<div><h1>H5页面</h1><div><p><!-- 显示选择相册的图片 --><img id="img"src=""></p></div><ul><li><button id="test">调用原生test</button></li><li><button id="sel">调用原生select选择相册</button></li></ul>
</div>
<script>window.onload = () => {document.querySelector('#test').addEventListener('click', () => {mg.test('我是来自web数据啦')})document.querySelector('#sel').addEventListener('click', async () => {const b64 = await mg.select()document.querySelector('#img').setAttribute('src', b64)})}
</script>
</body></html>
1.3.8. 执行网页JS
有时候,我们需要在原生端调用网页中 JS,完成一些业务需求。
(1)第一步:网页中挂载 JS到 window
重新运行项目,点击按钮调用注入的函数测试
<script>window.go = () => {return '我是网页JS函数'}window.onload = () => {// ...}
</script>
(2)原生端调用挂载的 JS
借助 webview 提供runJavaScript api 异步执行JavaScript脚本,并通过回调方式返回脚本执行的结果。
官方参考文档
// 3. 执行网页 jsrunJs() {// this.controller.loadUrl($rawfile('index.html'))this.controller.runJavaScript('go()', (error, res) => {if (error) {return AlertDialog.show({message: error.message})}// 获取执行返回值AlertDialog.show({message: res})})}build() {Navigation() {Button('执行网页 js').onClick(() => {this.runJs()})// ...}
}
1.4. 总结
本文介绍了在 HarmonyOS NEXT Developer Beta1 版本中,使用 ArkTS 进行混合开发时 Web 组件的基本用法。通过 Web 组件和 WebView API,可以轻松地在应用中嵌入和控制网页内容。以下是几个关键点的总结:
(1)基本语法:通过 Web 组件可以加载和显示网页,处理页面事件,并与网页进行交互。
(2)事件处理:支持多种事件处理,如页面开始加载、加载完成和加载出错、访问历史记录等。
(3)API 使用:WebView API 提供了丰富的方法,用于充当 Bridge 代理,更好和网页端进行通信。
通过本文的介绍,你应该能够初步掌握在 ArkTS 中使用 Web 组件的基本方法,并应用于实际开发中。混合开发可以让你充分利用 Web 技术的优势,同时享受 ArkTS 的高效开发体验。
相关文章:
HarmonyOS Web组件(二)
1. HarmonyOS Web组件 官方文档 1.1. 混合开发的背景和好处 混合开发(Hybrid Development)是一种结合原生应用和Web应用的开发模式,旨在同时利用两者的优势。随着移动应用需求的多样化和复杂化,单一的开发方式往往难以满足所有…...
HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 单选题序号2
基础认证题库请移步:HarmonyOS应用开发者基础认证题库 注:有读者反馈,题库的代码块比较多,打开文章时会卡死。所以笔者将题库拆分,单选题20个为一组,多选题10个为一组,题库目录如下,…...
基于python深度学习遥感影像地物分类与目标识别、分割实践技术应用
目录 专题一、深度学习发展与机器学习 专题二、深度卷积网络基本原理 专题三、TensorFlow与Keras介绍与入门 专题四、PyTorch介绍与入门 专题五、卷积神经网络实践与遥感图像场景分类 专题六、深度学习与遥感图像检测 专题七、遥感图像检测案例 专题八、深度学习与遥感…...
叶再豪降龙精英课程总结
文章目录 1.思维认知1.1 稻盛和夫成功公式1.2 龙头主升模式1.3 龙头主升-两种路径1.4 股市新手的炒股思路1.5 龙头案例1.6 降龙心法 2.情绪周期2.1 情绪周期2.1 情绪演绎周期2.2 情绪的四个部分2.2.1 指数的情绪周期2.2.3 热点情绪周期2.2.4 热点情绪演绎周期2.2.5 大热点支线2…...
算法 - 查找算法(顺序、折半、红黑树、AVL树、B+树、散列)
查找 顺序查找 查找算法原理: 顺序查找是一种简单的查找方法,从数组的第一个元素开始,依次比较每个元素,直到找到目标元素或者数组结束为止。 实现步骤: 从数组的第一个元素开始。逐一比较数组中的元素与目标值。如…...
TCP与UDP网络编程
网络通信协议 java.net 包中提供了两种常见的网络协议的支持: UDP:用户数据报协议(User Datagram Protocol)TCP:传输控制协议(Transmission Control Protocol) TCP协议与UDP协议 TCP协议 TCP协议进行通信的两个应用进程:客户端、服务端 …...
媲美Midjourney-v6,Kolors最新文生图模型部署
Kolors模型是由快手团队开发的大型文本到图像生成模型,专门用于将文本描述转换成高质量的图像。 Kolors模型支持中英文双语输入,生成效果与Midjourney-v6相媲美,能够处理长达256个字符的文本输入,具备生成中英文文字的能力。 Ko…...
深度学习程序环境配置
深度学习环境配置 因为之前轻薄本没有显卡跑不起来,所以换了台电脑重新跑程序,故记录一下配置环境的步骤及常见错误 本人数学系,计算机部分知识比较匮乏,计算机专业同学可以略过部分内容 深度学习环境配置 深度学习环境配置 CUD…...
【STM32 HAL库】全双工I2S+双缓冲DMA的使用
1、配置I2S 我们的有效数据是32位的,使用飞利浦格式。 2、配置DMA **这里需要注意:**i2s的DR寄存器是16位的,如果需要发送32位的数据,是需要写两次DR寄存器的,所以DMA的外设数据宽度设置16位,而不是32位。…...
【Spring Boot】网页五子棋项目中遇到的困难及解决方法
目录 一、HikariPool-1 - Starting异常二、Invalid bound statement (not found)异常三、The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary异常四、The server time zone value时区报错异常五、补充知识点…...
营销策划方案模板
这应该是目前最详细最完整的营销策划方案模板,营销公司内部都在使用的标准版本,你可以根据自己的营销内容直接填入这个模板,很快就能写好一份至少80分的营销策划方案。 如果暂时用不到也可以先收藏,以备不时之需。 废话不多说&a…...
Python入门基础教程(非常详细)
现在找工作真的越来越难了!今年更是难上加难 前几天在网上刷到这样一条热搜: #23岁找工作因年龄大被HR拒绝了# 是这个世界疯了还是我疯了? 合着只想要有20年以上工作经验的应届毕业生是吧 这好像就是现在的就业市场现状:“35岁…...
LeetCode 常见题型汇总
前30 22 生成括号 剪枝 51 N皇后 37 解数独 二分查找 69 求平方根 字典树 位运算 191 求1的个数 231 2的N次方 338 求0到N的比特位为1的个数 动态规划 并查集 LRU缓存 布隆过滤器...
el-select选择器修改背景颜色
<!--* FilePath: topSearch.vue* Author: 是十九呐* Date: 2024-07-18 09:46:03* LastEditTime: 2024-07-18 10:42:03 --> <template><div class"topSearch-container"><div class"search-item"><div class"item-name&quo…...
Shell程序设计
各位看官,从今天开始,我们进入新的专栏Shell学习,Shell 是操作系统的命令行界面,它允许用户通过输入命令与操作系统交互。常见的 Shell 有 Bash 和 Zsh,它们可以执行用户输入的命令或运行脚本文件。Shell 广泛应用于系…...
PyQT6---环境搭建
1、虚拟环境搭建 创建虚拟环境 create -n pyqt6_39 python3.9 切换虚拟环境 conda activate pyqt6_39 2、安装pyqt6 安装pyqt6和pyqt6-tools pip install PyQt6 -i https://pypi.tuna.tsinghua.edu.cn/simplepip install pyqt6-tools -i https://pypi.tuna.tsinghua.edu.cn/…...
whisper-api语音识别语音翻译高性能兼容openai接口协议的开源项目
whisper-api 介绍 使用openai的开源项目winsper语音识别开源模型封装成openai chatgpt兼容接口 软件架构 使用uvicorn、fastapi、openai-whisper等开源库实现高性能接口 更多介绍 https://blog.csdn.net/weixin_40986713/article/details/138712293 使用说明 下载代码安装…...
面试题:Java中堆内存和栈内存的区别,缓存数据是把数据放到哪里
目录 堆内存(Heap)栈内存(Stack)String字符串的hashcode缓存 在Java中,堆内存(Heap)和栈内存(Stack)是两种不同类型的内存区域。它们各自扮演着不同的角色,并…...
【开源库学习】libodb库学习(一)
Hello World Example 在本章中,我们将使用传统的“Hello World”示例展示如何创建一个依赖于ODB进行对象持久化的简单C应用程序。特别是,我们将讨论如何声明持久类、生成数据库支持代码以及编译和运行我们的应用程序。我们还将学习如何使对象持久化&…...
Java中SPI机制原理解析
使用SPI机制前后的代码变化 加载MySQL对JDBC的Driver接口实现 在未使用SPI机制之前,使用JDBC操作数据库的时候,一般会写如下的代码:// 通过这行代码手动加载MySql对Driver接口的实现类 Class.forName("com.mysql.jdbc.Driver") Dr…...
数学建模~~~SPSS相关和回归分析
目录 1.双变量相关分析 1.1理论基础 1.2简单散点图的绘制介绍 1.3相关性分析 1.4分析相关性结果 2.简单线性回归分析 2.1简单概括 2.2分析过程 2.3结果分析 3.曲线回归分析 3.1问题介绍 3.2分析过程 3.3结果分析 1.双变量相关分析 1.1理论基础 双变量相关分析并不…...
【Android】常用基础布局
布局是一种可用于放置很多控件的容器,它可以按照一定的规律调整内部控件的位置,从而编写出精美的界面,布局内不单单可以放控件,也可以嵌套布局,这样可以完成一些复杂的界面,下面就来认识一些常用的布局吧。…...
服务攻防-中间件安全(漏洞复现)
一.中间件-IIS-短文件&解析&蓝屏 IIS现在用的也少了,漏洞也基本没啥用 1、短文件:信息收集 2、文件解析:还有点用 3、HTTP.SYS:蓝屏崩溃 没有和权限挂钩 4、CVE-2017-7269 条件过老 windows 2003上面的漏洞 二.中…...
【SD】深入理解Stable Diffusion与ComfyUI的使用
【SD】深入理解Stable Diffusion与ComfyUI的使用 1. Stable Diffusion(SD)原理概述2. 各部件详解3. SD的工作流程4. ComfyUI与SD的结合5. 总结 1. Stable Diffusion(SD)原理概述 整体结构:SD不是单一模型,…...
Linux 12:多线程2
1. 生产者消费者模型 生产者消费者模型有三种关系,两个角色,一个交易场所。 三种关系: 生产者之间是什么关系?竞争 - 互斥 消费者和消费者之间?竞争 - 互斥 消费者和消费者之间?互斥和同步 两个角色: 生产者和消费者 一个交…...
Android RSA 加解密
文章目录 一、RSA简介二、RSA 原理介绍三、RSA 秘钥对生成1. 密钥对生成2. 获取公钥3. 获取私钥 四、PublicKey 和PrivateKey 的保存1. 获取公钥十六进制字符串1. 获取私钥十六进制字符串 五、PublicKey 和 PrivateKey 加载1. 加载公钥2. 加载私钥 六、 RSA加解密1. RSA 支持三…...
类与对象-多态-案例3-电脑组装具体实现
#include<iostream> #include<string> using namespace std; //CPU class CPU { public:virtual void calculate() 0; }; //显卡 class GraCard { public:virtual void graphics() 0; }; //存储 class Memory { public:virtual void memory() 0; }; class Compu…...
try-with-resources 语句的用途和优点有哪些,它如何自动管理资源?
在Java编程中,资源管理是一个重要的议题,尤其是当你在代码中使用那些需要显式关闭的资源,比如文件流、数据库连接或者网络套接字等。 如果资源使用完毕后忘记关闭,不仅会导致资源泄露,还可能引起程序性能问题甚至系统…...
GraphRAG参数与使用步骤 | 基于GPT-4o-mini实现更便宜的知识图谱RAG
首先给兄弟朋友们展示一下结论,一个文本18万多字,txt文本大小185K,采用GraphRAG,GPT-4o-mini模型,索引耗时差不多5分钟,消耗API价格0.15美元 GraphRAG介绍 GraphRAG是微软最近开源的一款基于知识图谱技术的框架&#…...
/秋招突击——7/21——复习{堆——数组中的第K大元素}——新作{回溯——全排列、子集、电话号码的字母组合、组合总和、括号生成}
文章目录 引言复习数组中的第K大的最大元素复习实现参考实现 新作回溯模板46 全排列个人实现参考实现 子集个人实现参考实现 电话号码的字母组合复习实现 组合总和个人实现参考实现 括号生成复习实现 总结 引言 昨天的科大讯飞笔试做的稀烂,今天回来好好练习一下&a…...
谁做违法网站/企业品牌策划
引言 线程池很普通的老话题,讨论的很多.深入的不多,也就那些基础库中才能见到这种精妙完备的技巧.而本文随大流 想深入简述一种高效控制性强的一种线程池实现. 先引入一个概念, 惊群. 简单举个例子. 春天来了, 公园出现了很多麻雀. 而你恰巧有一个玉米粒. 扔出去, 立马无数麻雀…...
重庆做网站优化推广的公司/站长之家域名
自主操作的水下机器人可以在从研究海洋到探索其他行星的各个领域中使用。普渡大学的科学家们开发了一种移动坞站,它不仅可以使这些机器停下来进行充电,还可以同时卸载其数据,从而为它们提供了一种无需人工输入即可长时间运行的方式。 我们已…...
集团网站建设案例/推广平台有哪些渠道
今天一起安装了4块1080的卡。也算有一些坑吧,记录一下。 1)1080显卡,驱动型号,tensorflow,cuda, cudnn 版本一定要一致。我的清单如下: ############################################# nvidia显卡…...
做旅游网站的好处/52种新颖的促销方式
所谓插入排序,就是检查第i个数字,若比它的左边的数字小,则进行交换,一直持续这个动作,直到它的左边的数字比它还要小,则停止。 #coding:utf-8def insertion_sort(nums): for i in range(1,len(nums)): …...
网站开发语言html/网站营销与推广
最近在研究行列转换。在2000版本中,一律用case 语句来完成,但是在2005中新增了pivot运算符,它让你能够将行级数据旋转成为列表数据,实现类似Excel数据透视表的功能,而不需要像先前版本的SQLServer一样使用CASE语句。 以…...
网站建设的流程推广方案/成品ppt网站国外
硬件环境介绍:最近花了两周终于建成了Hyper-V Failover Clustering,多数时间基本上用在了去了解HP的刀片服务器及VC模块配置,由于是第一次使用所以去查询了很多文档,经过此次部署也对HP的刀片服务器有了点基本了解。先介绍下所使用…...