从零开始开发纯血鸿蒙应用之网页浏览
从零开始开发纯血鸿蒙应用
- 〇、前言
- 一、优化菜单交互
- 1、BuilderFunction.ets
- 2、改造 PageTitleBar
- 二、网址打开
- 1、方式选择
- 1、使用浏览器打开
- 2、内部打开
- 2.1、声明权限
- 2.2、封装 WebViewPage
- 2.2.1、组件字段
- 2.2.2、aboutToAppear
- 2.2.3、onBackPress
- 2.2.4、标题栏
- 2.2.4、网页内容展示
- 2.3、实现效果
- 三、总结
〇、前言
一直以来,桌面应用也好,手机应用也罢,对于网址的访问,无非两种形式:用浏览器打开和自身内部打开,那么这两种方式,在鸿蒙应用开发框架中,又当如何实现呢?且看下文。
一、优化菜单交互
如果你没有跳过前面的几篇,那么应该知道,在文件内容编辑和查看界面的右上角菜单,我一直没有确定应该提供什么样的功能,现在,是时候替换其中一个了。
也同样是在前面的内容中,我已经利用 @BuilderParam 和 @Builder,将菜单从组件外传入,然而,这一组装饰器还有一种带参的使用方式,在进行改造之前,菜单的实现代码长成这样:


如果,我想要让“查看”这一菜单项的功能,为打开一个弹窗,仅是将 promptAction.showToast({message: "点击了查看"}) 换成 this.dialog.open(),不仅无法实现预期响应,反而还会带来应用奔溃的问题。
如果想要 this.dialog.oepn() 这种代码正常运行,就必须使用带参版的自定义构建函数,下面就跟着我的步骤进行改造。
1、BuilderFunction.ets
考虑到后续丰富 TxtEdit 功能时,可能会大量使用自定义构建函数,所以,不妨新建一个脚本文件,专门来存放这类代码,如此一来,相同的菜单实现内容,也可以很方便的进行多处使用。这个脚本,我本人是将其放在了lib_comps模块,如果屏幕前的你,有其他想法,尽管按照你的想法去按排。

大部分代码同之前的一样,区别就在于方法名变更,同时还增加了方法参数、一个类型为 MenuOption 的参数。$$ 是 ArkTS 语言提供的具有 双向绑定能力的运算符。
2、改造 PageTitleBar
相对应的,PageTitleBar 组件的实现代码也进行相应的变更:

而使用了 PageTitleBar 的相关页面,需要将具体的菜单功能逻辑,通过 PageTitleBar 的 viewOption 字段传入,例如下面:

二、网址打开
1、方式选择
既然打开网址有两种方式,那么就需要由用户自己选择对应的方式,所以,就需要一个对话框去询问用户:

这个对话框的实现效果如下:

1、使用浏览器打开
首先,看一下使用现成的系统浏览器打开网址,应当怎么样实现?
其实,原理还是调用第三方应用的那一套,也即用 common.UIAbilityContext.startAbility 的方式:

在拉起系统浏览器之前,先对用户输入的网址进行合法性校验,比如不能为空,以及限定为 http 协议。
2、内部打开
这种方式,想当然的,就需要封装一个专门的页面进行网页内容的展示,核心思想就是利用鸿蒙开发框架现成的 WebView API 和 Web 组件。
2.1、声明权限
打开线上网页,需要使用网络,所以,需要声明 ohos.permission.INTERNET 权限,同时,一些网页的正在运作需要定位权限,因此,可以一并在 Entry 模块的 module.json5 文件中,用 requestPermissions 标签,将所有权限声明好:

对于由系统授权的权限,可以只写权限名,而对于需要用户授予的权限,除了权限名,使用原因和使用方式都必须写明。
2.2、封装 WebViewPage
整体代码如下:

按照从上到下的顺序,逐个部分进行讲解。
2.2.1、组件字段
WebViewPage 一共声明定义了四个字段:
1)ctx:关联UI上下文的字段
2)root:定义页面根组件 Column 样式的字段
3)webController:获取控制Web组件的控制器实例的字段
4)url:保存拉起当前页面传入的网址的字段
2.2.2、aboutToAppear
在 WebViewPage 中,声明周期函数 aboutToAppear 需要做的事情有两件,一是将网址从路由参数中解析出来,二是向用户申请定位权限。

2.2.3、onBackPress
onBackPress 函数,不是声明周期函数,而是页面级的事件函数,对应返回事件,当用户使用返回手势和返回按钮时,就会调用该函数。WebViewPage 之所以不保持 onBackPress 的默认实现,是为了兼容 网页后退和app页面后退。
Web 组件,作为呈现网页内容的组件,具备了像浏览器那样记忆网页访问顺序的能力,也即内置了网页栈;当网页栈中不止一个网页,那么就可以进行网页后退,反之就不行;而确定当前 Web 组件能不能进行网页后退,可以利用 WebController 提供的 accessBackward 进行判断:

所以,onBackPress 就可以使用如下的代码去实现页面返回的兼容处理:

onBackPress 的返回值,是有特殊含义的;返回 true 时,表示返回事件由当前页面自行处理,返回 false 则表示由系统默认逻辑处理。
2.2.4、标题栏
由于 WebViewPage 需要在标题栏右侧,提供一个触发网页刷新的控件,所以,不适合直接用事先封装好的 PageTitleBar 组件,需要现场设计一个:

标题栏,理所应当要用行布局,并且是两端对齐、黑色背景。整个标题栏一共有三个控件,最左侧是返回控件,一样是兼容网页回退和app页面回退;中间部分是页面标题,固定显示内容”网页浏览“,并且当用户点击该控件时,会将网页内容滚回顶部位置;最右侧是刷新网页的控件,用户点击它就会触发网页刷新。
标题栏的三个控件中,除了返回控件外,剩下的两个,其交互实现都是基于 WebviewController 的。
2.2.4、网页内容展示
展示网页内容,可以用鸿蒙框架的内置组件 Web:

使用时,有几个组件属性必须设置好:

1)JavaScriptAccess 属性

现在的网页,大部分在实现时都会用到大量的 Javascript 代码,所以开启支持才能保证大部分网页可以被正常显示出来。
2)domStorageAccess 属性

不同于 JavaScriptAccess 属性的默认开启,domStorageAccess 属性是默认关闭的,然而,鉴于许多网页会用到 DOM Storage API,所以,设置为开启比较好。
3)onGeolocationShow
Web 组件有一个 geolocationAccess(geolocationAccess: boolean) 属性,设置是否开启获取地理位置权限,并且默认是开启的,然而,由于定位权限是用户授权的,因此,鸿蒙应用市场审核要求,规定使用Web组件且用到定位能力时,必须向用户弹窗申请定位权限,而这个申请弹窗,就可以放在 onGeolocationShow 中进行实现:

2.3、实现效果
最终,上述代码运作时的实现效果如下:

三、总结
本篇围绕如何在纯血鸿蒙应用中,实现网址打开操作,先后介绍了带参数的自定义构建函数的使用,调用系统浏览器的实现,以及如何封装 WebViewPage。值得重点学习的,理当首推封装 webViewPage 的部分,基于该部分,可以扩展地探索开发浏览器的实现方案。
相关文章:
从零开始开发纯血鸿蒙应用之网页浏览
从零开始开发纯血鸿蒙应用 〇、前言一、优化菜单交互1、BuilderFunction.ets2、改造 PageTitleBar 二、网址打开1、方式选择1、使用浏览器打开2、内部打开2.1、声明权限2.2、封装 WebViewPage2.2.1、组件字段2.2.2、aboutToAppear2.2.3、onBackPress2.2.4、标题栏2.2.4、网页内…...
【大模型LLM】DeepSeek LLM Scaling Open-Source Language Models with Longtermism
深度探索LLM:以长期主义扩展开源语言模型 0.论文摘要 开源大语言模型(LLMs)的快速发展确实令人瞩目。然而,以往文献中描述的扩展规律得出了不同的结论,这为LLMs的扩展蒙上了一层阴影。我们深入研究了扩展规律&#…...
分布式事务-本地消息表学习与落地方案
本文参考: 数据库事务系列04-本地消息表实现分布式事务 基础概念 本地消息表实现分布式事务最终一致性的核心:是通过上游本地事务的原子性持久性,配合中间件的重试机制,从而实现调用下游的最终一致性。 这里有几个要点可以解析一…...
Debezium系列之:记录一次源头数据库刷数据,造成数据丢失的原因
Debezium系列之:记录一次源头数据库刷数据,造成数据丢失的原因 一、背景二、查看topic日志信息三、结论四、解决方法一、背景 源头数据库在很短的时间内刷了大量的数据,部分数据在hdfs丢失了 理论上debezium数据采集不会丢失,就需要排查数据链路某个节点是否有数据丢失。 …...
PHP约课健身管理系统小程序源码
🏋️♂️ 约课健身管理系统小程序:重塑健身预约体验,引领数字化健身新时代 一款基于ThinkPHPUniapp框架,由米扬精心雕琢的约课健身管理系统小程序,专为健身房、健身工作室、运动会所、运动场馆、瑜伽馆、拳馆等泛健…...
Java之泛型
文章目录 首先接着上一篇(集合)文章,来个非常牛逼的易错题传统集合问题分析泛型快速入门案例泛型介绍泛型的好处泛型的语法泛型的声明泛型的实例化泛型使用举例泛型使用的注意事项和细节 自定义泛型自定义泛型方法 自定义泛型接口自定义泛型方…...
图论 之 最小生成树
文章目录 题目1584.连接所有点的最小费用 最小生成树MST,有两种算法进行求解,分别是Kruskal算法和Prim算法Kruskal算法从边出发,适合用于稀疏图Prim算法从顶点出发,适合用于稠密图:基本思想是从一个起始顶点开始&#…...
STM32-有关内存堆栈、map文件
STM32堆栈空间大小设置_stm32堆栈分配大小-CSDN博客 STM32堆栈的大小及内存四(五)区的分析 - 天街小雨润地狠 - 博客园 .map文件的位置...
Linux系统中常见的词GNU是什么意思?
GNU 是 “GNU’s Not Unix” 的递归缩写,它是一个自由软件项目,旨在创建一个完全自由的操作系统。这个名字反映了GNU项目的核心理念:它试图创建一个类Unix的系统,但不是Unix本身。 GNU 项目由 理查德斯托曼(Richard S…...
【个人开源】——从零开始在高通手机上部署sd(二)
代码:https://github.com/chenjun2hao/qualcomm.ai 推理耗时统计 单位/ms 硬件qnncpu_clipqnncpu_unetqnncpu_vaehtp_cliphtp_unethtp_vae骁龙8 gen124716.994133440.39723.215411.097696.327 1. 下载依赖 下载opencv_x64.tar,提取码: rrbp下载opencv_aarch64.t…...
【MCU驱动开发概述】
MCU驱动开发概述 目录 MCU驱动开发概述二、驱动开发的目的三、驱动开发的关键组成部分四、示例 - LED 控制驱动 一、引言 MCU(Microcontroller Unit),即微控制器单元,是一种集成在单个芯片上的计算机系统,通常用于控制…...
PC端Linux之虚拟CAN
在调试QT程序时候需要用到虚拟CAN进行发送和接收的操作,以此记录方法。 在调试QT程序时候需要用到虚拟CAN进行发送和接收的操作,以此记录方法。 1、安装can-utils sudo apt install can-utils ifconig -a【查看是否安装成功,是否有can0网络…...
C++:std::thread、条件变量与信号量
介绍 在多线程编程的世界里,协调不同线程之间的工作是一项极具挑战性的任务。线程可能需要等待特定条件的满足,或者对共享资源的访问进行限制。C 标准库为我们提供了强大的工具,如 std::thread 用于创建和管理线程,条件变量用于线…...
POI pptx转图片
前言 ppt页面预览一直是个问题,office本身虽然有预览功能但是收费,一些开源的项目的预览又不太好用,例如开源的:kkfileview pptx转图片 1. 引入pom依赖 我这个项目比较老,使用版本较旧 <dependency><gro…...
Java File 类
File 类是 Java 中用于处理文件和目录的基本类之一,位于 java.io 包中。它提供了多种方法来创建、删除、检查、修改文件或目录的属性,以及列出文件夹中的内容。虽然 File 类本身不提供直接的读取或写入文件内容的方法(这些操作通常由 FileInp…...
工业通信协议 EtherNet/IP 全面解析
工业通信协议 EtherNet/IP 全面解析 EtherNet/IP(以太网工业协议)是一种基于标准以太网的工业自动化通信协议,由 ODVA(开放设备网供应商协会) 管理。它融合了 CIP(通用工业协议) 和以太网技术&…...
使用docker配置PostgreSQL
配置docker阿里云镜像仓库 国内使用docker hub拉取镜像比较慢,所以首先配置个人的镜像仓库。 阿里云的个人镜像仓库是免费的,对个人来说足够用。 具体操作参考阿里云官方链接 。 关于个人镜像仓库的使用参考链接。 配置完个人镜像仓库后将公网配置到doc…...
UITextView删除原有字符串时,光标会上移并且光标会变高
代码运行效果如图: import Foundationclass TestVC: UIViewController {override func viewDidLoad() {super.viewDidLoad()let testV MyCustomTextView(frame: CGRect(x: 0, y: 130, width: SCREEN_WIDTH - 50, height: 170))self.view.addSubview(testV)testV.ba…...
python入门 介绍及变量的使用
1.python介绍 python 是一门计算机语言 常见的计算机语言:python、java、C语言。。。 什么是计算机语言:就是让计算机知道你想干什么,把你的需求使用它能听懂的语言说出来 中国也有一门计算机语言:易语言 能认为是语言的本质上…...
51单片机-按键
1、独立按键 1.1、按键介绍 轻触开关是一种电子开关,使用时,轻轻按开关按钮就可使开关接通,当松开手时,开关断开。 1.2、独立按键原理 按键在闭合和断开时,触点会存在抖动现象。P2\P3\P1都是准双向IO口,…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
前端调试HTTP状态码
1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...
