深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
Demo/entry
应用主模块,应用入口,存放代码、资源的路径;Demo/entry/src/main/module.json5
模块配置文件,类似 Android 项目中的AndroidManifest.xml
:
{
"module": {
"name": "entry", // 当前module的名字,module打包成hap后,表示hap的名称,标签值采用字符串表示(最大长度31个字节),该名称在整个应用要唯一
"type": "entry", // 表示模块的类型,类型有三种,分别是entry、feature和har
"srcEntry": "./ets/DemoAbilityStage.ts", // 模块的入口文件路径,默认没有,需要手动创建,类似 Android 中的 Application
"description": "$string:module_desc", // 当前模块的描述信息
"mainElement": "EntryAbility", // 该标签标识hap的入口ability名称或者extension名称。只有配置为mainElement的ability或者extension才允许在服务中心露出
"deviceTypes": [ // 该标签标识hap可以运行在哪类设备上
"phone",
"tablet"
],
"deliveryWithInstall": true, // 该模块是否随应用一起安装
"installationFree": false, // 释放支持免安装
"pages": "$profile:main_pages", // ability 中使用的 page 信息配置
"abilities": [ // ability 配置列表,类似 Android 中的 Activity 列表
{
"name": "EntryAbility", // 逻辑名,整个应用要唯一
"srcEntry": "./ets/entryability/EntryAbility.ts", // 入口代码路径
"description": "$string:EntryAbility_desc", // 描述信息
"icon": "$media:icon", // 图标,如果为 MainElement,必填,此处配置影响应用列表显示及任务栈显示
"label": "$string:EntryAbility_label", // 标签名,此处配置影响应用列表显示及任务栈显示
"startWindowIcon": "$media:icon", // 启动页图标
"startWindowBackground": "$color:start_window_background", // 启动页背景颜色
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}
使用的图标:
名称资源:
{
"string": [
{
"name": "EntryAbility_label",
"value": "Ability1"
}
]
}
在桌面显示:
在任务栈显示:
如果有多个 UIAbility
,则配置了 skills
为 entity.system.home
的都会在桌面创建图标:
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
Demo/entry/src/main/ets
源码文件路径;Demo/entry/src/main/ets/entryability/EntryAbility.ts
UI 组件,类似 Android 中的Activity
;Demo/entry/src/main/resources
资源文件路径;
项目架构及与Android对比
从总体的项目架构来看,HarmonyOS 项目是比较贴近 Android 项目中 Compose + 单Activity 架构的,并且我们在 HarmonyOS 中也能找到一些与 Android 项目对应的关系:
Android | HarmonyOS | ||
---|---|---|---|
settings.gradle.kts | 项目配置文件 | Demo/build-profile.json5 | 项目配置文件,不同的是将应用的签名、SDK版本、多渠道配置移动到了这里 |
build.gradle.kts | 模块配置文件 | Demo/AppScope/app.json5 | 应用配置文件,配置包名、版本、图标、名称 |
AndroidManifest.xml | 清单文件 | Demo/entry/src/main/module.json5 | 模块配置文件,配置应用入口、路由等信息 |
Application | 应用程序入口 | AbilityStage | 应用程序入口 |
Activity | UI组件 | UIAbility | UI组件 |
Navgation | 页面路由 | pages | 页面路由 |
生命周期
在 module.json5
中的 module
节点声明 srcEntry
,我们也能和 Android 应用一样配置一个全局的应用程序入口,拥有类似的生命周期方法回调:
import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class DemoAbilityStage extends AbilityStage {
onCreate() {
// 应用启动回调
}
}
而 HarmonyOS 中的UI组件 UIAbility
也和 Android 中的 Activity
有着类似的生命周期:
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 组件创建
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy() {
// 组件销毁
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
// window 创建
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
// 设置布局,显示 ets/pages/Index.ets 的布局
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
// window 销毁
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground() {
// 进入前台
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground() {
// 进入后台
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
HarmonyOS 的 UIAbility
没有 Android 中 Activity
的 onResume
onPause
生命周期回调方法,当然如果需要的话还是有方案可以实现的,需要在 onWindowStageCreate
方法里,通过 windowStage
实现:
onWindowStageCreate(windowStage: window.WindowStage) {
windowStage.on('windowStageEvent', (event) => {
// event 取值为枚举类型 window.WindowStageEventType
if(event === window.WindowStageEventType.ACTIVE) {
// 获取焦点
} else {
// 失去焦点
}
})
}
布局
HarmonyOS 使用 ArkTS 作为开发语言,并且提供 ArkTS UI 组件用于UI布局,就像上面 UIAbility
中显示的布局 ets/pages/Index.ets
:
@Entry // 声明这个组件可作为页面入口,即在 UIAbility 中加载或进行页面跳转
@Component // 声明这是一个UI组件
struct Index {
@State message: string = 'Hello World'
build() {
// 声明布局
Row() { // 横向布局
Column() { // 竖向布局
Text(this.message) // 文本控件
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%') // 宽度铺满
}
.height('100%') // 高度铺满
}
}
上面是新建项目默认生成的布局,效果是在屏幕中间显示 Hello World
文本,更多组件可参考组件参考(基于ArkTS的声明式开发范式。
界面跳转
Pages 跳转
HarmonyOS 生成的项目里,默认只有一个 UIAbility
,并通过 windowStage.loadContent
来加载显示布局,因此一种多界面的方式就是编写不同的 Page,在不同的 Page 直接跳转;
首先,我们在 ets/pages
路径下新建一个 Second.ets
文件,并参照 Index.ets
声明布局,并添加按钮用于返回上一级:
import router from '@ohos.router'
@Entry
@Component
struct Second {
@State message: string = 'Second Page'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按钮
Button("点击返回")
.onClick(() => {
// 按钮点击通过 router 返回上一级
router.back()
})
}
.width('100%')
}
.height('100%')
}
}
然后,我们需要在 resources/base/profile/main_pages.json
文件中添加这个界面的声明:
{
"src": [
"pages/Index",
"pages/Second"
]
}
在之前的 Index.ets
布局中添加按钮并配置点击跳转逻辑:
import router from '@ohos.router'
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按钮
Button("点击跳转")
.onClick(() => {
// 按钮点击通过 router 跳转到 pages/Second
router.pushUrl({
url: "pages/Second"
})
})
}
.width('100%')
}
.height('100%')
}
}
这样通过点击按钮就能进行界面的跳转了。上面创建 Page 的方式推荐在 ets/pages
路径使用 New -> Page
进行创建,会自动生成对应的布局文件和配置,更便捷且不容易出错。
UIAbility 跳转
虽然 HarmonyOS 官方提供的模板里面都只有一个 UIAbility
,但是它还是支持多 UIAbility
的;
同样的在 ets
路径下参照 EntryAbility.ts
创建一个新的 SecondEntryAbility.ts
,在 onWindowStageCreate
中加载布局 pages/SecondAblity
,在 module.json5
中添加对应的配置即可,这里还是推荐使用 New -> Ability
进行创建;
在 ets/pages/SecondAbility.ets
中修改文本及添加返回按钮:
import common from '@ohos.app.ability.common'
@Preview
@Entry
@Component
struct SecondAbility {
@State message: string = 'Second Ability'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button("点击返回")
.margin({ top: 30 })
.onClick(() => {
// 按钮点击关闭当前 UIAbility
let context = getContext(this) as unknown as common.UIAbilityContext
context.terminateSelf()
})
}
.width('100%')
}
.height('100%')
}
}
然后我们修改 ets/pages/Index.ets
中的代码,在之前的按钮下方添加一个新的按钮点击跳转 SecondEntryAbility
:
import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button("点击跳转")
.onClick(() => {
// 按钮点击跳转到 SecondEntryAbility
let context = getContext(this) as unknown as common.UIAbilityContext
let want: Want = {
deviceId: "",
bundleName: "com.sample.demo",
abilityName: "SecondEntryAbility",
}
context.startAbility(want)
})
// 添加按钮
**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**



**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**
钮
**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

[外链图片转存中...(img-xkEiEKI7-1715730546509)]
[外链图片转存中...(img-r0h2rgMg-1715730546509)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**