2024年鸿蒙最全写给Android开发者的HarmonyOS入门指南(3),2024年最新程序员面试

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合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,则配置了 skillsentity.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 项目对应的关系:

AndroidHarmonyOS
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应用程序入口
ActivityUI组件UIAbilityUI组件
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');
  }
}

HarmonyOSUIAbility 没有 AndroidActivityonResume 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)
          })
        // 添加按钮


**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

![](https://img-blog.csdnimg.cn/direct/743b668910224b259a5ffe804fa6d0db.png)
![img](https://img-blog.csdnimg.cn/img_convert/e1688fd9be704965ef8b48bd54f45750.png)
![img](https://img-blog.csdnimg.cn/img_convert/8c8b470c4dec8fb69974946d2a030a88.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**

钮


**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

![](https://img-blog.csdnimg.cn/direct/743b668910224b259a5ffe804fa6d0db.png)
[外链图片转存中...(img-xkEiEKI7-1715730546509)]
[外链图片转存中...(img-r0h2rgMg-1715730546509)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值