鸿蒙开发从入门到跨平台第一篇:深入了解鸿蒙项目的核心结构



大家好,我是拭心。


上篇文章《# 深圳打响第一枪!鸿蒙技术是否有前途的最强信号来了》 提到,深圳已经发了 2024 年关于鸿蒙软件生态的规划,如果目标达到,过几年很有可能出现 iOS Android 鸿蒙三足鼎立的情况,因此我们客户端程序员有必要储备一下鸿蒙知识。


接下来我将分几篇文章介绍鸿蒙开发的入门、实战和跨平台相关知识,今天这篇文章作为开篇,主要介绍一下鸿蒙开发使用的 IDE 和一个简单工程的项目结构,解决读者在刚接触鸿蒙开发时一脸茫然、无从下手的问题。


IDE



鸿蒙开发的 IDE 叫做 DevEco Studio,它是基于 IntelliJ IDEA Community 的开源版本打造,和 Android Studio 血脉相通,因此做过 Android 开发或者使用过 IDEA 的工程师们切换到鸿蒙开发时,会发现查看项目目录、文件结构、调试/运行、设备选择、日志、命令行等都是相同的位置,像回家一样自然,非常顺滑。


新建项目页面也类似:



上两图是开发鸿蒙和 Android 应用时新建项目的页面,可以看到两者很相似。在鸿蒙中,Ability 类似 Android 的 Activity,IDE 提供了一些典型业务的 Ability 实例工程;另外鸿也提供了类似 JNI 的 NApi 工程,用于开发需要调用 C++ 的项目。


项目结构


当我们使用 DevEco Studio 新建一个鸿蒙项目后,创建的项目长这样:



AppScope


按照上图中从上往下的顺序(忽略前两个文件夹 .hvigor .idea,不重要),第一个比较重要的文件夹是 AppScope



AppScope 的作用是配置 app 的核心信息,包括唯一标识(bundleName)、版本号、icon 和名称等等。新建项目后我们一般都会修改这些内容,这时候就需要修改上图中的 app.json5 文件。


.json5 是鸿蒙项目中配置文件的格式,这个格式结尾的文件就是配置文件(好像是句废话哈哈).


第二个重要的文件夹是 entry,它是鸿蒙项目的默认入口代码目录,内容比较多我们稍后介绍。


hvigor


第三个文件夹是 hvigor



hvigor 是鸿蒙项目的构建工具(可以类比 Gradle),支持使用 JavaScript/TypeScript 开发配置脚本。


根目录下的 hvigor 文件夹用来配置构建工具的版本号、用到的插件、执行配置、日志配置、调试配置等信息:



当我们需要升级 hvigor 本身或者官方构建插件(@ohos/hvigor-ohos-plugin)的版本号时,需要去 hvigor/hvigor-config.json5 文件中修改(文件内容见上图右侧)。


  1. 如果编译速度慢,需要修改这个文件的 execution 部分,比如开启守护进程、打开增量编译和并行编译。
  2. 如果调试的时候经常断开(可能是内存不够),可以试一下把这个文件的 nodeOptions 属性的 maxOldSpaceSize 参数调大一点(单位是 MB)。


hvigor 依赖 node,因此在开发鸿蒙项目时我们需要安装并配置 node 环境。


了解 hvigor 是什么后,接下来看下项目根目录下的 hvigorfile.ts 文件。


hvigorfile.ts 是用来配置项目的构建校本,我们可以在其中创建自定义的 task 和 plugin(两者差不多,不同在于 plugin 方便项目之间复用),然后添加到项目的构建流程中。



由于配置文件是 ts 文件格式,因此自定义 hvigor 构建 task 很简单,只需要定义一个 pluginId、实现 run 方法即可。


在上图中,我们的 myTask 函数就是一个自定义的 task,它的 id 是 myTask,然后在任务的执行方法里打印了一条日志。


自定义 plugin 也是类似的,区别在于需要继承 HvigorPlugin:



自定义 task/plugin 函数以后,我们把它添加到导出的 plugins 数组即可。


了解 hvigor 及 hvigorfile.ts 文件后,接下来我们看看根目录下另外比较重要的两个文件。


build-profile.json5



build-profile.json5 用来配置 app 的签名信息、使用的 SDK 版本号、构建模式和多 module 信息。


签名信息配置在 signingConfigs 中:



如上图所示,签名信息可以有多个,每个配置信息主要包括它的名称、使用的证书和密钥信息、密码等文件。


构建模式配置在 buildModeSet 中:



和开发 Android 应用类似,开发鸿蒙应用时也支持对不同包(比如 debug 包和 release 包)做不同的配置,其中比较关键的有这几个:


  1. externalNativeOptions:项目有 C/C++ 代码时需要配置,比如 CMakeList 文件路径、参数、ABI 类型等等
  2. napLibFilterOption:项目里有 .so 文件冲突时,在这里配置使用规则,比如 pickFirsts、excludes


build-profile.json5 中最后一个关键的配置信息是 modules,即模块配置信息。


在大点的项目里一般会有多个模块,当我们新建一个模块后,就需要在 build-profile.json5 文件的 modules 属性中加一个配置:



配置信息包括模块名称、路径、产物信息等。


比较可惜的是,目前 build-profile.json5 文件还不支持条件语句,这在大型项目编译时可是刚需啊。毕竟很多时候业务只想编译自己用到的那几个模块,如果能像 Gradle 一样根据 properties 文件里的值修改配置信息就好了,希望华为可以早点支持这个功能。


oh-package.json5


oh-package.json5 和前端项目里的 package.json 文件类似,主要用来声明项目名称、版本号、描述、入口和依赖信息。



一个项目里会有多个 oh-package.json5 文件,除了根目录下,每个模块都有自己的 oh-package.json5 文件。


当模块有导出文件时,就需要在 oh-package.json5 的 main 属性填写要导出的文件名称,比如 index.ets


oh-package.json5 中声明的依赖信息,在项目打开或者手动点击 Sync And Refresh Project 后 ohpm 会下载对应的库到当前目录的 oh_modules 文件夹下:



ohpm 是鸿蒙的包管理工具,类似 npm。


当我们在不同项目里用到同一个三方库时,为了避免版本冲突,可以在项目根目录下的 oh-package.json5 里强制指定版本号:



上图中在 overrides 中配置的三方库版本号将作为最终使用的版本。


entry


介绍完上面的文件和文件夹作用后,终于到了最重要的 entry 目录:



entry 的名字不重要,重点是它的内容,每个新建的模块内容都一样。


从上图可以看到,entry 目录下也有 build-profile.json5、hvigorfile.ts 和 oh-package.json5 文件,这是因为在鸿蒙项目里,每个模块可以单独配置自己的构建流程和依赖信息。


模块中最重要的配置文件却不在这三者之间,而是 src/main/module.json5。


module.json5



module.json5 文件用来配置一个模块的名称、类型、进程信息和入口等,其中比较关键的配置有这些:


  1. type: 表示当前模块的类型,类型有:entry(项目入口)、feature(动态特性包)、har(静态包)、shared(动态共享包)。一般来说项目的入口模块类型是 entry,其他业务模块的类型是 feature,纯粹的库类型为 shared
  2. mainElement:表示当前模块的入口 UIAbility 名称,名词要和后面的 abilities 中声明的一致
  3. deviceType:表示当前模块可以运行在哪类设备上,支持的值为 phone、tablet、tv、wearable、car(可以看到,鸿蒙能开发的应用类型还是很多的)
  4. pages:当前模块的页面路由配置文件路径,默认为 src/main/resources/base/profile/main_pages.json
  5. abilities:当前模块里的所有 UIAbility 信息


UIAbility 的配置信息有这些:


  1. name:组件名称,前面的 mainElement 中写的要和这里的一致
  2. srcEntry:UIAbility 文件的相对路径
  3. launchType:当前 Ability 的启动模式
  4. startWindowIcon:启动页面的 icon
  5. skills:当前 UIAbility 能够接收的 Want 特征


UIAbility 的启动模式有三种:


  1. multition:多实例,每次启动都新创建一个
  2. singleton:单例模式,只有第一次启动创建
  3. specified:指定模式,运行时由开发者决定是否创建新实例


记得很多年前 Android 面试中 Activity 的启动模式经常被问到,鸿蒙的 UIAbility 启动模式或许以后也是个考察点,可以重点关注下。


skills 标签表示 UIAbility 被启动时能够接收的 Want 特征,那什么是 Want 呢?



Want 是在组件启动时传递的对象,比如在 UIAbilityA 中要启动 UIAbilityB 时,可以通过定义一个 Want 对象传递数据给 UIAbilityB 。


根据是否指定要打开的 Ability 信息,Want 分为两种:


  1. 显式 Want:通过 bundleName 和 abilityName 确定了要打开的 Ability 是什么
  2. 隐式 Want:没有明确指定要打开的 Ability 名称,而是通过 action、entities 定义要使用的内容,由系统匹配支持的应用来处理


可以看到,鸿蒙的 Want 类似 Android 的 Intent。


回到 skills,skills 就是用来声明这个 UIAbility 支持的能力,包括 entities、actions 和 uris 属性:



actions 表示能够接收的行为,包括系统预定义的和自定义的。entities 和它类似,暂时没搞清楚两者区别。


一个 app 可以配置多个具有入口能力的 skills标签(即配置了ohos.want.action.homeentity.system.home)。


OK,这就是一个模块的 module.json5 文件核心属性。


其他



介绍完上面的内容,entry 文件夹中剩下的就是 cpp、ets 和 resources 文件夹。


  1. cpp 用于保存 cpp/h 和 CMakeLists.txt 文件(可以没有)
  2. ets 用于存放 .ts 和 .ets 文件(鸿蒙的代码格式)
  3. resources 用于保存字符串、颜色值、图片和路由配置等信息


到这里我们就了解了 entry 目录的主要内容及作用。


总结


好了,这篇文章到这里就结束了,主要讲了:


  1. 鸿蒙开发和 Android 开发 IDE 的相似性,降低读者对鸿蒙开发上手的担忧
  2. 鸿蒙项目的关键文件、文件夹的作用,让读者对鸿蒙项目的各个组成部分有更深入的认识


在这篇文章中,我们刻意略过了一些鸿蒙技术名词的含义(比如 Ability),这是因为它展开的内容很多,我们刚接触鸿蒙开发时先不了解这么多,先对鸿蒙项目有个整体的认识,当要修改相关信息时,知道该改哪里,就够了。


后面的文章我们会逐步介绍鸿蒙开发的语言、框架和跨平台技术细节,感兴趣可以持续关注哦~


感谢你的阅读,欢迎留下你对这篇文章以及鸿蒙开发的想法,以及你想了解的鸿蒙开发知识,我们下期再见!



0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
拭心shixin
下载 APP