鸿蒙APP应用开发教程—超详细的项目结构说明

1. 新建项目

打开DevEco Studio, 选择 Create Project:

1.1 选择模版

Create Project - Choose Template

1.2 配置项目

Create Project - Configure Project

如果使用的是 DevEco 3.X 版本, 可以根据 Compile SDK版本选择不同的模式, 比如:

  • 3.0.0(API 8)及更早 - 仅支持 FA模式, 支持 ArkTS语言和 JS语言

  • 3.1.0(API 9) - 支持Stage 和 FA 模式, 仅支持ArkTS语言

如果使用的DevEco 4.X 版本,则默认就是 Stage模式和ArkTS语言, 且不支持切换模式和语言, 但是支持选择nodejs 版本:

从工具默认选择看:

  • Satge 模式 是官网主推模式
  • ArkTS语言是官方主推语言, 后续不再支持创建选择JS语言
  • 不再默认支持低代码模式(Enable Super Visual)
  • 支持的Device从 Phone到 Tablet 以及 2in1.
  • 支持自定义主入口名称 entry, 可更像 Android那样设置为 app
  • 支持选择 nodejs 版本

2. 项目结构

2.1 Stage模型应用

根据官方的表述 Stage模型的应用包结构如下,

  • 一个应用入口 Entry.hap
  • 一到多个功能Feature.hap
@startuml
node "App Pack(xxx.app)"{
    
    node "Entry.hap" {
        [ets] as 0
        [resources] as 1
        [libs] as 2
        [resources.index] as 3
        [module.json] as 4
    }
    node  "FeatureA.hap" {
        [ets] as 5
        [resources] as 6
        [libs] as 7
        [resources.index] as 8
        [module.json] as 9
    }
    node "FeatureB.hap" {
        [ets] as 10
        [resources] as 11
        [libs] as 12
        [resources.index] as 13
        [module.json] as 14
    }  
    component pak.info
    Entry.hap -d[hidden]- FeatureA.hap
    FeatureA.hap -d[hidden]- FeatureB.hap
    FeatureB.hap -d[hidden]- pak.info  
}
@enduml

每个应用项目必须在项目的代码目录下加入配置文件,这些配置文件会向编译工具、操作系统和应用市场提供应用的基本信息。

在基于Stage模型开发的应用项目代码下,都存在一个app.json5及一个或多个module.json5这两种配置文件。

app.json5主要包含以下内容:

  • 应用的全局配置信息,包含应用的包名、开发厂商、版本号等基本信息。
  • 特定设备类型的配置信息。

module.json5主要包含以下内容:

  • Module的基本配置信息,例如Module名称、类型、描述、支持的设备类型等基本信息。
  • 应用组件信息,包含UIAbility组件和ExtensionAbility组件的描述信息。
  • 应用运行过程中所需的权限信息。

具体到上面的项目, app.json5如下:

{
  "app": {
    "bundleName": "net.devwiki.hmdemo", // 类似于包名
    "vendor": "example", // id
    "versionCode": 1000000, // 版本号
    "versionName": "1.0.0", // 版本名称
    "icon": "$media:app_icon", // 图标
    "label": "$string:app_name" // 名称
  }
}

其中:

  • icon 为 AppScope/resources/base/media 文件夹下的 app_icon.png
  • label 为 AppScope/resources/base/string.json 中的 app_name
{
  "string": [
    {
      "name": "app_name",
      "value": "HMDemo"
    }
  ]
}

此处以 HM3Demo为例,项目文件夹结构如下:

各个文件夹及文件说明如下:

  • .hvigor : 项目编译构建文件夹(可忽略)
  • .idea : IDEA项目配置文件夹(可忽略)
  • AppScope > app.json5:应用的全局配置信息。
  • entry:HarmonyOS工程模块,编译构建生成一个HAP包。
    • src > main > ets:用于存放ArkTS源码。
    • src > main > ets > entryability:应用/服务的入口。
    • src > main > ets > pages:应用/服务包含的页面。
    • src > main > resources:用于存放应用/服务所用到的资源文件,如图形、多媒体、字符串、布局文件等。关于资源文件,详见资源分类与访问。
    • src > main > module.json5:Stage模型模块配置文件。主要包含HAP包的配置信息、应用/服务在具体设备上的配置信息以及应用/服务的全局配置信息。具体的配置文件说明,详见module.json5配置文件。
    • build-profile.json5:当前的模块信息、编译信息配置项,包括buildOption、targets配置等。其中targets中可配置当前运行环境,默认为HarmonyOS。
    • hvigorfile.ts:模块级编译构建任务脚本,开发者可以自定义相关任务和代码实现。
  • hvigor : 项目插件配置

2.2 程序入口entry

DevEco 3.x 的项目中程序入口为默认的 entry 模块, 在DevEco 4.x 版本可以自定义名称为 app。

在 entry(app)模块的ets/entryability目录下的 EntryAbility.ts为程序入口:

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) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    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() {
    // 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');
  }
}

此处为 UIAbility的子类, UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。

UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。

在 entry 的 module.json5 配置中配置了入口, "mainElement": "EntryAbility",,

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ]
  }
}

在 EntryAbility 的 onWindowStageCreate 函数中 指定了启动页面:

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    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) ?? '');
    });
  }

入口页面的内容为一个文本框:

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

2.3 资源文件

资源文件存储在 entry/src/main/resources目录内,包含:

  • base : 通用的文件目录
    • element : 包含字符串,颜色等资源文件
    • media: 包含多媒体资源文件
    • profile : 包含 page里面的UI路由配置文件
  • 语言_国家: I18N资源文件
    • 子目录和base 类似
  • rawfile : raw 资源文件目录

3. 构建配置

和Android项目类似, 鸿蒙APP项目有应用级别构建配合和模块级别构建配置:

  • 根目录的 build-profile.json5
  • module 目录下的 build-profile.json5

3.1 应用构建配置

项目根目录 build-profile.json5文件为构建配置:

{
  "app": {
    "signingConfigs": [],
    "compileSdkVersion": 9,
    "compatibleSdkVersion": 9,
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
      }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        {
          "name": "default",
          "applyToProducts": [
            "default"
          ]
        }
      ]
    }
  ]
}

API Version 9、API Version 8与API Version 4~7的构建体系不同,因此在设置编译构建信息时也存在差异:

  • API Version 9:需要对构建配置文件、构建脚本、应用依赖的共享包等信息进行设置。
    • build-profile.json5:应用/服务构建配置文件。
    • hvigorfile.ts:自定义编译构建脚本。
    • oh-package.json5:应用的三方包依赖,支持共享包的依赖。
  • API Version 8:需要对构建配置文件、构建脚本、应用依赖的npm包等信息进行设置。
    • build-profile.json5:HarmonyOS应用/服务构建配置文件。
    • hvigorfile.ts:自定义编译构建脚本。
    • package.json:应用的三方包依赖,支持HAR(遵循npm标准规范)和npm包的依赖。
  • API Version 4~7:需要通过build.gradle来对工程编译构建参数进行设置。

常用的字段说明如下:

{
  "app": { 
    //工程的签名信息,可包含多个签名信息
    "signingConfigs": [  
      {
        "name": "default",  //标识签名方案的名称
        "type": "HarmonyOS",  //标识HarmonyOS应用
        //该方案的签名材料
        "material": {  
          "certpath": "D:\\SigningConfig\\debug_hos.cer",  //调试或发布证书文件,格式为.cer
          "storePassword": "******",  //密钥库密码,以密文形式呈现
          "keyAlias": "debugKey",  //密钥别名信息
          "keyPassword": "******",  //密钥密码,以密文形式呈现
          "profile": "D:\\SigningConfig\\debug_hos.p7b",  //调试或发布证书Profile文件,格式为.p7b
          "signAlg": "SHA256withECDSA",  //密钥库signAlg参数
          "storeFile": "D:\\SigningConfig\\debug_hos.p12"  //密钥库文件,格式为.p12
        }
      }
    ],
    "compileSdkVersion": 9,  //指定HarmonyOS应用/服务编译时的SDK版本
    "compatibleSdkVersion": 9,  //指定HarmonyOS应用/服务兼容的最低SDK版本
    //定义构建的产品品类,如通用默认版、付费版、免费版等
    "products": [  
      {
        "name": "default",  //定义产品的名称,支持定制多product目标产物,具体请参考定制多目标构建产物
        "signingConfig": "default",  //指定当前产品品类对应的签名信息,签名信息需要在signingConfigs中进行定义
      }
    ]
  },
  "modules": [
    {
      "name": "entry",  //模块名称
      "srcPath": "./entry",  //标明模块根目录相对工程根目录的相对路径
      "targets": [  //定义构建的APP产物,由product和各模块定义的targets共同定义
        {
          "name": "default",  //target名称,由各个模块的build-profile.json5中的targets字段定义
          "applyToProducts": [  
            "default"   //表示将该模块下的“default” Target打包到“default” Product中
          ]
        }
      ]
    }
  ]
}

3.2 module构建配置

在 entry 模块的目录也有一个 build-profile.json文件:

{
  "apiType": 'stageMode',
  "buildOption": {
  },
  "targets": [
    {
      "name": "default",
      "runtimeOS": "HarmonyOS"
    },
    {
      "name": "ohosTest",
    }
  ]
}

详细的字段说明如下:

{
  "apiType": 'faMode',  //API类型,支持FA和Stage模型
  "showInServiceCenter": true,  //是否在服务中心展示
  "buildOption": {
    //配置筛选har依赖.so资源文件的过滤规则
    "napiLibFilterOption": {
      //按照.so文件的优先级顺序,打包最高优先级的.so文件
      "pickFirsts": [
        "**/1.so"
      ],
      //按照.so文件的优先级顺序,打包最低优先级的.so 文件
      "pickLasts": [
        "**/2.so"
      ],
      //排除的.so文件
      "excludes": [
        "**/3.so"
      ],
      //允许当.so重名冲突时,使用高优先级的.so文件覆盖低优先级的.so文件
      "enableOverride": true
    },
    //cpp相关编译配置
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",  //CMake配置文件,提供CMake构建脚本
      "arguments": "",  //传递给CMake的可选编译参数
      "abiFilters": [  //用于设置本机的ABI编译环境
        "armeabi-v7a",
        "arm64-v8a"
      ],
      "cppFlags": ""  //设置C++编译器的可选参数
    },
  },
  "targets": [  //定义的Target,开发者可以定制不同的Target,具体请参考定制多目标构建产物
    {
      "name": "default",
      "runtimeOS": "HarmonyOS",
    },
    {
      "name": "ohosTest",
    }    
  ]
}

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了几套最新版的HarmonyOS NEXT学习资源

获取完整版高清学习路线,请点击→《HarmonyOS教学视频

HarmonyOS教学视频

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取白皮书:请点击→《鸿蒙生态应用开发白皮书V2.0PDF

在这里插入图片描述

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. .……

在这里插入图片描述


二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

在这里插入图片描述

三、如何快速入门?《鸿蒙基础入门学习指南》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. .……

在这里插入图片描述


四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. .……

在这里插入图片描述


五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 7.网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. .……

在这里插入图片描述


更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/474229.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】堆和树详解堆和二叉树的实现堆的top-k问题

主页:醋溜马桶圈-CSDN博客 专栏:数据结构_醋溜马桶圈的博客-CSDN博客 gitee:mnxcc (mnxcc) - Gitee.com 目录 1.树概念及结构 1.1 树的概念 2.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用 2.二叉树的概念及结构 2.1 二叉树的概念…

力扣389周赛复盘

字符串及其反转中是否存在同一子字符串 class Solution {public boolean isSubstringPresent(String s) {StringBuilder sb new StringBuilder(s);String reverse sb.reverse().toString(); for (int i 0; i < s.length() - 2; i) { // 修改循环终止条件为 <&#xf…

matlab实现对全球不规则投影数据的投影转换

前几个专栏我们讨论了几个不规则的投影转换问题&#xff0c;有需要的可以阅读以下文章&#xff1a; matlab实现对极地投影数据的投影转换_matlab极地投影-CSDN博客 联合matlab和Arcgis进行netcdf格式的雪覆盖数据的重新投影栅格-CSDN博客 这次遇到的问题是一个墨卡托投影的数据…

【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用

【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用 文章目录 【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用参考资料一、初识WebFlux1、什么是函数式编程1&#xff09;面向对象编程思维 VS 函数式编程思维&#xff08;封装、继承和多态描述事物间…

vue3新功能-Teleport

1.teleport 在组件内的任何位置渲染内容 将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。 例:将组件dialog添加到body下面 <teleport to"body"> <el- dialog --> </teleport> 2.fragments 多个根元素外层不需要…

2024年了,还能学自动化吗?

大家都说2024年软件测试行业会卷的更厉害&#xff0c;简单的功能测试不再是入门的标准&#xff0c;那么2024年是否可以从自动化测试这块冲一把呢&#xff1f; 我们先来看看过去的一年自动化测试在测试行业中的发展分析&#xff1a; 01 市场需求增长 随着技术的进步和企业对软件…

爬虫入门系列-HTML基础语法

&#x1f308;个人主页&#xff1a;会编辑的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” HTML基础语法 bs4解析比较简单&#xff0c;但是呢&#xff0c;首先你需要了解一丢丢的html知识&#xff0c;然后再去使用bs4去提取&#xff0c;逻辑和编写难度就会非常简…

消息队列常见的两种消费模式

一、点对点模式 点对点模式&#xff1a;生产者发送消息到消息队列&#xff0c;消费者从消息队列中接收、处理消息&#xff0c;消息被消费后&#xff0c;就不在消息队列中了。每个消息只能由一个消费者接收和处理。如果有多个消费者监听同一个队列&#xff0c;消息将被发送到其…

刷题DAY29 | LeetCode 491-递增子序列 46-全排列 47-全排列 II

491 递增子序列&#xff08;medium&#xff09; 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;也…

流畅的 Python 第二版(GPT 重译)(五)

第九章. 装饰器和闭包 有人对将这个功能命名为“装饰器”的选择提出了一些抱怨。主要的抱怨是该名称与其在 GoF 书中的用法不一致。 名称 decorator 可能更多地归因于其在编译器领域的用法—语法树被遍历并注释。 PEP 318—函数和方法的装饰器 函数装饰器让我们在源代码中“标记…

外包干了14天,技术退步明显。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;2019年我通过校招踏入了成都一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

NVIDIA Chat with RTX教程使用以及CUDA和CUDNN

基本环境安装&#xff1a;CUDA12.1CUDNNcudnn-windows-x86_64-8.9.7.29_cuda12-archive 1、CUDA下载 CUDA官方安装教程: https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html CUDA Toolkit的下载: CUDA Toolkit 12.1 Downloads | NVIDIA Dev…

Vue.js+SpringBoot开发高校宿舍调配管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统展示四、核心代码4.1 查询单条个人习惯4.2 查询我的室友4.3 查询宿舍4.4 查询指定性别全部宿舍4.5 初次分配宿舍 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的…

如何读懂Java GC日志

Java应用程序的GC日志对分析定位很多性能问题有着非常大的帮助。默认情况下&#xff0c;Java应用程序不会自动产生GC日志。如果需要输出GC日志&#xff0c;必须在JVM启动时增加对应的参数&#xff0c;场景的参数如表5-8所示。 2. GC日志分析一 例如&#xff0c;在Tomcat的JVM启…

【Spring Cloud】微服务注册中心的工作原理

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;学习技术栈 个性签名&#xff1a;人生乏味啊&#xff0c;我欲令之光怪陆离 本文封面由 凯楠&#x1f4f7; 友情提供&#xff01; 目录 前言 1. 注册中心的主要作用 2. 常见的注册中心 3. Nacos 服务注册和发…

护眼大路灯哪个更适合学生?大路灯购选分享,经验总结!

在当前开节奏的生活领域中&#xff0c;作为测评师我观察到&#xff0c;大路灯作为一种新型照明的补光工具&#xff0c;逐渐被越来越多的人融入家庭生活中。这种设备无疑为用眼人群带来了显著的好处。但许多用户反馈中也频繁提及平时是眼睛疲劳感越来越严重等副情况&#xff0c;…

Java 学习和实践笔记(42):内部类(inner class)

内部类的两个要点: 1&#xff09;内部类提供了更好的封装。只能让外部类直接访问&#xff0c;不允许同一个包中的其他类直 接访问。 2&#xff09;内部类可以直接访问外部类的私有属性&#xff0c;内部类被当成其外部类的成员。但外部类 不能访问内部类的内部属性。| 注意&…

【开源】SpringBoot框架开发个人保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 保险档案模块2.3 保险订单模块2.4 保险理赔模块 三、系统展示四、核心代码4.1 查询保险产品4.2 新增保险预定4.3 订单支付4.4 新增理赔单4.5 查询保险理赔 五、免责说明 一、摘要 1.1 项目介绍 基于J…

停车管理系统asp.net+sqlserver

停车管理系统asp.netsqlserver 说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net架构和sql server数据库&#xff0c; 功能模块&#xff1a; 停车管理系统asp.net sqlserver 用户功能有菜单列表 我的停车记录 专…

【解决】Unity Profiler | Sempaphore.WaitForSignal

开发平台&#xff1a;Unity 2022 版本以上 开发语言&#xff1a;CSharp 6.0 编程平台&#xff1a;Visual Studio 2022 关键词&#xff1a;Sempaphore.WaitForSignal   问题背景 开发过程中出现 Waiting to excute code… 长时间阻碍运行。使用 逐对象排查法 确认影响无法运行…