Harmony开发笔记(未完成)
一、感想
作为一名拥有11年经验的Android开发者,我亲历了Android从高速发展到如今面临“僧多粥少”的过程。技术的世界瞬息万变,没有一种技术能够让人依赖一辈子。去年初,我自学了鸿蒙系统,并顺利通过了鸿蒙官方的初级和高级认。

然而,由于一年来几乎没有实际应用,很多知识已经生疏。如今,我决定重新拾起鸿蒙开发,并通过笔记记录学习过程。
二、Harmony工程目录结构

在工程目录下,存在以下文件/文件夹:
AppScope, entry,hvigor,build-profile.json5,code-linter.json,hvigorfile.ts,oh-package.json5,oh-package-lock.json5。
build-profile.json5:工程级配置信息,包括签名signingConfigs、产品配置products等,模块信息在此处配置。
{"app": {"buildModeSet": [{"name": "debug"},{"name": "release"}],"products": [{"buildOption": {"strictMode": {"caseSensitiveCheck": true,"useNormalizedOHMUrl": true}},"compatibleSdkVersion": "5.0.2(14)","name": "default","runtimeOS": "HarmonyOS","signingConfig": "default"}],"signingConfigs": []},"modules": [{"name": "entry","srcPath": "./entry","targets": [{"applyToProducts": ["default"],"name": "default"}]}]
}
code-linter.json:是代码检查工具的配置文件,用于定义代码风格和质量规则。
hvigorfile.ts:工程级编译构建任务脚本
oh-package.json5:主要用来描述全局配置,如:依赖覆盖(overrides)、依赖关系重写(overrideDependencyMap)和参数化配置(parameterFile)等
oh-package-lock.json5:是依赖锁文件,用于精确记录当前项目中所有依赖的实际安装版本及其依赖树结构。它的作用是确保在不同环境中安装的依赖版本完全一致,避免因依赖版本不一致导致的问题。

AppScope:包含了resources 和 app.json5
resources:全局使用的资源,如图片、字符串等
app.json5:应用信息
{"app": {"bundleName": "com.zzw.harmonyapp","vendor": "example","versionCode": 1000000,"versionName": "1.0.0","icon": "$media:app_icon","label": "$string:app_name"}
}
entry:这个就跟Android的 app 一样的作用了

entry 之中也包含了:build-profile.json5,hvigorfile.ts,oh-package.json5。三个的作用上面做了介绍,区别在于entry中的是针对模块级别的。
entry目录中的其他元素,后面专门学习介绍。
hvigor:包含了hvigor-config.json5文件,hvigor-config.json5是 HarmonyOS 开发中用于配置 Hvigor 构建工具 的配置文件。Hvigor 是 HarmonyOS 的构建工具,类似于 Android 的 Gradle,用于管理项目的构建、依赖和任务执行。
三、ArkTS语法
ArkTs 是基于TypeScript 的语言,又“遥遥领先”了,跟前端的语法有点类似,主要记载一些常用的,要熟悉还是得靠日常的积累。
1.ArkTS的基本组成

四、沉浸式效果
在开发App时候,都会有个占满整个屏幕的Splash(启动)页面,鸿蒙开发同样有个启动页:
@Entry
@Component
struct Splash {@State message: string = 'Hello World';build() {Stack() {Image($r('app.media.app_bg_splash')).width('100%').height('100%')}.width('100%').height('100%')}
}
整个页面就一张图片,希望整张图片充满整个屏幕,运行后效果:

这个明显不是期望的效果。
来看看遥遥领先官方的说明:
典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条,其中状态栏和导航条,通常在沉浸式布局下称为避让区;避让区之外的区域称为安全区。开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感,从而使用户获得最佳的UI体验。

从这里可以看出来,上面应用截图中的启动页,只有应用界面的区域,启动页的图片并没有占位到状态栏和导航条。
开发应用沉浸式效果主要要考虑如下几个设计要素:
- UI元素避让处理:导航条底部区域可以响应点击事件,除此之外的可交互UI元素和应用关键信息不建议放到导航条区域。状态栏显示系统信息,如果与界面元素有冲突,需要考虑避让状态栏。
- 沉浸式效果处理:将状态栏和导航条颜色与界面元素颜色相匹配,不出现明显的突兀感。
针对上面的设计要求,可以通过如下两种方式实现应用沉浸式效果:
a.窗口全屏布局方案:调整布局系统为全屏布局,界面元素延伸到状态栏和导航条区域实现沉浸式效果。当不隐藏避让区时,可通过接口查询状态栏和导航条区域进行可交互元素避让处理,并设置状态栏或导航条的颜色等属性与界面元素匹配。当隐藏避让区时,通过对应接口设置全屏布局即可。
b.组件安全区方案:布局系统保持安全区内布局,然后通过接口延伸绘制内容(如背景色,背景图)到状态栏和导航条区域实现沉浸式效果。
以下将分别用这两种方案实现。
4.1 窗口全屏布局方案
窗口全屏布局方案主要涉及以下应用扩展布局,全屏显示,不隐藏避让区和应用扩展布局,隐藏避让区两个应用场景。
4.1.1 应用扩展布局,全屏显示,不隐藏避让区
/*应用扩展布局,全屏显示,不隐藏避让区*/static setFullScreenNoHiddenBar(windowStage: window.WindowStage): void {let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口// 1. 设置窗口全屏let isLayoutFullScreen = true;windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {console.info('Succeeded in setting the window layout to full-screen mode.');}).catch((err: BusinessError) => {console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));});}
显示效果:

4.1.2 应用扩展布局,隐藏避让区
/*应用扩展布局,全屏显示,隐藏避让区*/static setFullScreenHiddenBar(windowStage: window.WindowStage): void {let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口// 1. 设置窗口全屏let isLayoutFullScreen = true;windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {console.info('Succeeded in setting the window layout to full-screen mode.');}).catch((err: BusinessError) => {console.error(`Failed to set the window layout to full-screen mode. Code is ${err.code}, message is ${err.message}`);});// 2. 设置状态栏隐藏windowClass.setSpecificSystemBarEnabled('status', false).then(() => {console.info('Succeeded in setting the status bar to be invisible.');}).catch((err: BusinessError) => {console.error(`Failed to set the status bar to be invisible. Code is ${err.code}, message is ${err.message}`);});// 2. 设置导航条隐藏windowClass.setSpecificSystemBarEnabled('navigationIndicator', false).then(() => {console.info('Succeeded in setting the navigation indicator to be invisible.');}).catch((err: BusinessError) => {console.error(`Failed to set the navigation indicator to be invisible. Code is ${err.code}, message is ${err.message}`);});}
效果如下:

4.2 组件安全区方案
应用未使用setWindowLayoutFullScreen()接口设置窗口全屏布局时,默认使能组件安全区布局。
应用在默认情况下窗口背景绘制范围是全屏,但UI元素被限制在安全区内(自动排除状态栏和导航条)进行布局,来避免界面元素被状态栏和导航条遮盖。
4.2.1 设置窗口背景色
通过设置整个窗口的背景色,和应用颜色一致,实现全屏的效果:
static setWindowBackgroundColor(windowStage: window.WindowStage,colorStr:string): void {windowStage.getMainWindowSync().setWindowBackgroundColor(colorStr);}
效果如下(这里为了便于观察,颜色和应用颜色不一致):

4.2.2 使用expandSafeArea属性扩展安全区域
状态栏和导航条颜色不同时,可以用如下方案:
import { window } from '@kit.ArkUI';@Entry
@Component
struct Splash {@State message: string = 'Hello World';build() {Stack() {Image($r('app.media.app_bg_splash')).width('100%').height('100%').expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) // 图片组件的绘制区域扩展至状态栏和导航条。}.width('100%').height('100%')}
}
效果如下:

通过上面四种方法的实现,在对应的场景下使用对应的方案,就非常清楚了。
五、页面的跳转
在Android的开发中,有了启动页,接下来就是从启动页跳转到主页了,然后关闭启动页。同样的鸿蒙也是需要这样做。
组件导航(Navigation)和页面路由(@ohos.router)均支持应用内的页面跳转,但组件导航支持在组件内部进行跳转,使用更灵活。组件导航具备更强的一次开发多端部署能力,可以进行更加灵活的页面栈操作,同时支持更丰富的动效和生命周期。因此,推荐使用组件导航(Navigation)来实现页面跳转以及组件内的跳转,以获得更佳的使用体验。
5.1 @ohos.router (页面路由)(不推荐)
在启动页中,通过router进行跳转到主页:
import { router } from '@kit.ArkUI';@Entry
@Component
struct Splash {// 定时器 ID(用于跳转前取消定时器)private timerId: number = -1;build() {Stack() {Image($r('app.media.app_bg_splash')).width('100%').height('100%')}.width('100%').height('100%')}// 页面显示时触发onPageShow() {// 设置 1.5 秒后跳转this.timerId = setTimeout(() => {// 跳转到 Main 页面,并清除 Splash 页面router.replaceUrl({ url: 'pages/Main' });}, 1500); // 1500ms = 1.5秒}// 页面隐藏时触发(清除定时器)onPageHide() {if (this.timerId !== -1) {clearTimeout(this.timerId);}}
}
在这个使用了 router.replaceUrl,会将splash 进行替换成主页Main。
router.pushUrl :将Main压入栈之中,并不会清除Splash。
5.2 组件导航 (Navigation)(推荐)

看上面这张图,Navigation 更适合类似 Android 中一个Activity多个fragment 的形式,用于管理多个fragment。这点跟 Android 还是很像的,遥遥领先。
在这里不拓展Navigation的用法,再后面进行使用介绍。
附上官网中Navigation和Router的对比:
| 业务场景 | Navigation | Router |
|---|---|---|
| 一多能力 | 支持,Auto模式自适应单栏跟双栏显示 | 不支持 |
| 跳转指定页面 | pushPath & pushDestination | pushUrl & pushNameRoute |
| 跳转HSP中页面 | 支持 | 支持 |
| 跳转HAR中页面 | 支持 | 支持 |
| 跳转传参 | 支持 | 支持 |
| 获取指定页面参数 | 支持 | 不支持 |
| 传参类型 | 传参为对象形式 | 传参为对象形式,对象中暂不支持方法变量 |
| 跳转结果回调 | 支持 | 支持 |
| 跳转单例页面 | 支持 | 支持 |
| 页面返回 | 支持 | 支持 |
| 页面返回传参 | 支持 | 支持 |
| 返回指定路由 | 支持 | 支持 |
| 页面返回弹窗 | 支持,通过路由拦截实现 | showAlertBeforeBackPage |
| 路由替换 | replacePath & replacePathByName | replaceUrl & replaceNameRoute |
| 路由栈清理 | clear | clear |
| 清理指定路由 | removeByIndexes & removeByName | 不支持 |
| 转场动画 | 支持 | 支持 |
| 自定义转场动画 | 支持 | 支持,动画类型受限 |
| 屏蔽转场动画 | 支持全局和单次 | 支持 设置pageTransition方法duration为0 |
| geometryTransition共享元素动画 | 支持(NavDestination之间共享) | 不支持 |
| 页面生命周期监听 | UIObserver.on('navDestinationUpdate') | UIObserver.on('routerPageUpdate') |
| 获取页面栈对象 | 支持 | 不支持 |
| 路由拦截 | 支持通过setInterception做路由拦截 | 不支持 |
| 路由栈信息查询 | 支持 | getState() & getLength() |
| 路由栈move操作 | moveToTop & moveIndexToTop | 不支持 |
| 沉浸式页面 | 支持 | 不支持,需通过window配置 |
| 设置页面标题栏(titlebar)和工具栏(toolbar) | 支持 | 不支持 |
| 模态嵌套路由 | 支持 | 不支持 |
相关文章:
Harmony开发笔记(未完成)
一、感想 作为一名拥有11年经验的Android开发者,我亲历了Android从高速发展到如今面临“僧多粥少”的过程。技术的世界瞬息万变,没有一种技术能够让人依赖一辈子。去年初,我自学了鸿蒙系统,并顺利通过了鸿蒙官方的初级和高级认。…...
观成科技:海莲花“PerfSpyRAT”木马加密通信分析
1.概述 在2024年9月中旬至10月,东南亚APT组织“海莲花”通过GitHub发布开源安全工具项目,针对网络安全人员发起了定向攻击。通过对相关攻击活动进行分析,可以将其与一些海莲花的样本关联起来。这些样本的通信数据结构与海莲花此前使用的攻击…...
Spring Boot @Async 注解深度指南
Spring Boot Async 注解深度指南 一、核心使用要点 启用异步支持 必须在启动类或配置类添加 EnableAsync,否则异步不生效。 SpringBootApplication EnableAsync public class Application { ... }线程池配置 默认问题:Spring 默认使用 SimpleAsyncTaskEx…...
windows设置暂停更新时长
windows设置暂停更新时长 win11与win10修改注册表操作一致 ,系统界面不同 1.打开注册表 2.在以下路径 \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键新建 DWORD 32位值,名称为FlightSettingsMaxPauseDays 根据需求填写数…...
Orange 开源项目 - 集成百度智能云-千帆大模型
1 集成百度智能云-千帆大模型 百度智能云-千帆ModelBuilder百度智能云千帆大模型服务与开发平台ModelBuilder(以下简称千帆ModelBuilder)是面向企业开发者的一站式大模型开发及服务运行平台。千帆ModelBuilder不仅提供了包括文心一言底层模型和第三方开源…...
特斯拉 FSD 算法深度剖析:软件层面全解读
一、引言 特斯拉的 FSD(Full Self-Driving)系统作为自动驾驶领域的前沿成果,其软件层面的算法设计至关重要。本文将从软件的角度,深入探讨特斯拉 FSD 所采用的算法,包括感知、规划、控制等多个方面,以期为…...
2025/2/17--2/23学习笔记(week1)_C语言
1 整数的存储 只有整数才有原码,反码,补码,原码取反加一(除了符号位)得到补码。补码的补码会变成原码。 在任何位运算里,都是操作的补码,因为整数在内存里都是以补码存储的 2 移位运算符 移位…...
数据结构:二叉树的数组结构以及堆的实现详解
目录 一.树与二叉树 1.树的概念与相关术语: 2.二叉树: (1)定义: (2)特殊的二叉树: (3)完全二叉树 (4)二叉树的存储结构&#x…...
AWS S3 如何设置公开访问权限?
1.让整个bucket都有公开访问权限 1.1关闭【阻止公共读】 1.2关闭ACL访问控制 1.3打开桶策略 这样桶内所有的图片就能访问了 2.只开放特定文件让其具有访问权限? 2.1关闭【阻止公共读】 如之前的图示 2.2打开ACL控制 2.3单个文件打开公共读...
使用TortoiseGit配合BeyondCompare实现在Git仓库中比对二进制文件
使用TortoiseGit的比对工具可以直接右键,点击选择比对和上一版本的变化差异: 但是TortoiseGit只能支持比对纯文本文件的变化差异,如果尝试比对二进制文件,会提示这不是一个有效的文本文件: BeyondCompare可以比对二进制…...
8、HTTP/1.0和HTTP/1.1的区别【高频】
第一个是 长连接: HTTP/1.0 默认 短连接,(它也可以指定 Connection 首部字段的值为 Keep-Alive实现 长连接)而HTTP/1.1 默认支持 长连接,HTTP/1.1是基于 TCP/IP协议的,创建一个TCP连接是需要经过三次握手的…...
Rk3568驱动开发_开发环境的搭建_1
1、环境说明: 需要用官方的程序包,这个程序需要在虚拟机里编译再将镜像烧录到板子里,本质上是给板子上一套Linux操作系统,镜像是.img文件 Linux操作系统被分成了多个模块,编译好后储存在镜像里,本质上就和…...
Solr中得Core和Collection的作用和关系
Solr中得Core和Collection的作用和关系 一, 总结 在Apache Solr中,Core和Collection 是两个核心概念,他们分别用于单机模式和分布式模式(SolrCloud)中,用于管理和组织数据。 二,Core 定义&am…...
Visual Studio Code 远程开发方法
方法1 共享屏幕远程控制,如 to desk, 向日葵 ,像素太差,放弃 方法2 内网穿透 ssh 第二个方法又很麻烦,尤其是对于 windows 电脑,要使用 ssh 还需要额外安装杂七杂八的东西;并且内网穿透服务提供商提供的…...
如何看到 git 上打 tag 的时间
在 Git 中可以通过以下方法查看标签(tag)的创建时间: 使用 git show 命令: 运行以下命令可以查看某个特定标签的详细信息,包括创建时间: git show 输出中会包含 Tagger 的信息和 Date 字段,显示…...
【HarmonyOS Next】鸿蒙TaskPool和Worker详解 (一)
【HarmonyOS Next】鸿蒙TaskPool和Worker详解 (一) 一、TaskPool和Worker如何实现多线程?各自特点是什么? 在鸿蒙中通过TaskPool和Worker实现多线程并发,两者都基于Actor并发模型实现。 Actor并发模型,每…...
如何设置HTTPOnly和Secure Cookie标志?
设置HttpOnly和Secure标志于Cookie中是增强Web应用安全性的重要措施。这两个标志帮助防止跨站脚本攻击(XSS)和中间人攻击(MitM)。下面是关于如何设置这些标志的具体步骤: 设置方法 在服务器端设置 根据你的服务器端…...
几个api
几个api 原型链 可以阅读此文 Function instanceof Object // true Object instanceof Function // true Object.prototype.isPrototypeOf(Function) // true Function.prototype.isPrototypeOf(Object) // true Object.__proto__ Function.prototype // true Function.pro…...
Deepseek本地部署指南:在linux服务器部署,在mac远程web-ui访问
1. 在Linux服务器上部署DeepSeek模型 要在 Linux 上通过 Ollama 安装和使用模型,您可以按照以下步骤进行操作: 步骤 1:安装 Ollama 安装 Ollama: 使用以下命令安装 Ollama: curl -sSfL https://ollama.com/install.s…...
基于 DeepSeek+AutoGen 的智能体协作系统
用 AutoGen 实现智能体协作流程,假设团队里的 3 个角色,让 3 个角色相互交流后并给出不同方案,最后进行总结。下面是实现的思路,欢迎一起学习交流。 一、系统设计 1. sre_engineer_01 - 问题诊断与初步解决方案 职责:…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
Python的__call__ 方法
在 Python 中,__call__ 是一个特殊的魔术方法(magic method),它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时(例如 obj()),Python 会自动调用该对象的 __call__ 方法…...
EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...
