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 - 问题诊断与初步解决方案 职责:…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
