自 HarmonyOS 4.0 于 2023 年 8 月 4 日发布以来,有关 HarmonyOS 不再与安卓兼容的消息络绎不绝,这对跨平台框架行业造成了相当大的冲击,例如 Tarojs、UniApp 等。随着 HarmonyOS 系统的不断完善,许多应用开发商都期待着将其应用移植到 HarmonyOS 平台上。为了实现应用的快速迁移,跨平台框架需要提供适配 HarmonyOS 的解决方案,并支持 HarmonyOS 平台。
作为一位跨端框架的前端开发者,为了能够尽快实现鸿蒙的适配,不得不参与鸿蒙4.0的开发,自此开启了鸿蒙开发之路。
下面会站在前端开发者的角度,试图去理解一下鸿蒙OS 的开发。
前言
作为一名前端开发,混迹于 vscode、chrome、node、npm 之中多年,为写的每一行编译时与运行时的代码负责,基本上属于所见即所得。除了引用第三方依赖,基本上没有能黑盒的代码,并且还不知道对项目有什么作用的情况。但是,我现在要开始进行鸿蒙开发了。
作为一名鸿蒙开发,首先相关吃饭的工具得知道安装和使用,官方有安装文档,主要的东西就下面两个
一个开发者工具DevEco-Studio,一个模拟器Emulator。从前端的角度就是一个vscode ,一个调试版本的移动端的chrome。只不过没有像 chrome 的 dev-tools 那样的工具,大部分调试都能在DevEco-Studio中进行。
ArkTs 是一款基于 typescript 开发的语言,所以作为前端来说,功能编写时还是比较容易上手的。而我们做适配的,是基于安卓的功能实现,在鸿蒙上实现对应功能的,因为安卓的实现是使用了 java,因此在做适配开发时,使用最多的也是单例模式 + ArkTs 的组合。对于前端JS 开发者来说,单例模式会相对使用的比较少,而为了开发鸿蒙更高效,单例模式是基础模式,了解单例模式是非常必要的。除此之外,可能会比较经常使用还有装饰器模式,工厂模式,组合模式,迭代器模式。当然可能还有其他的模式,但开发鸿蒙至今,了解并经常使用到的是以上五种模式。与js上经常使用的设计模式相比,这些还是需要再加强一下学习一下。当然,对于有 typescript 开发经验的人,以上模式应该也相对的司空见惯了。以下简单举个示例
ArkTs
// 单例模式
class Singleton {
private static instance: Singleton;
private constructor() { }
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
public someBusinessLogic() {
// ...
}
}
function clientCode() {
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
if (s1 === s2) {
console.log('Singleton works, both variables contain the same instance.');
} else {
console.log('Singleton failed, variables contain different instances.');
}
}
clientCode();
ArkTs
// 工厂模式
interface AbstractFactory {
createProductA(): AbstractProductA;
}
interface AbstractProductA {
usefulFunctionA(): string;
}
class ConcreteProductA1 implements AbstractProductA {
public usefulFunctionA(): string {
return 'The result of the product A1.';
}
}
class ConcreteProductA2 implements AbstractProductA {
public usefulFunctionA(): string {
return 'The result of the product A2.';
}
}
class ConcreteFactory1 implements AbstractFactory {
public createProductA(): AbstractProductA {
return new ConcreteProductA1();
}
}
class ConcreteFactory2 implements AbstractFactory {
public createProductA(): AbstractProductA {
return new ConcreteProductA2();
}
}
function clientCode(factory: AbstractFactory) {
const productA = factory.createProductA();
}
clientCode(new ConcreteFactory1());
clientCode(new ConcreteFactory2());
应用模型 - Stage 模型
HarmonyOS4.0 上使用的应用模型是Stage模型 ,HarmonyOS早期版本支持的是FA模型 ,目前已不再主推,因此关注Stage模型即可。
该模型的应用组件包含以下两类
- UIAbility 组件:包含UI界面,提供展示UI的能力,主要用于和用户交互。 在鸿蒙的 entry 模块中进行派生。(类似于前端应用的 app.js 入口文件部分)
- ExtensionAbility 组件:提供特定场景(如卡片、输入法)的扩展能力,满足更多的使用场景。
应用配置
每个应用都包含应用配置文件,主要用于向编译工具、操作系统、应用市场提供应用的基本信息。
在基于Stage模型开发的应用项目代码下,都存在一个 app.json5 配置文件、以及一个或多个 module.json5 配置文件。
md
├─┬ AppScope
│ ├── resources -------------------------------------- App资源
│ └── app.json5 -------------------------------------- App全局配置
├─┬ entry -------------------------------------------- 入口模块
│ ├─┬ src ------------------------------------------ 入口模块源码
│ │ └─┬ main
│ │ └── module.json5 ----------------------------- 入口模块的基本配置
│ ├── build-profile.json5 -------------------------- 入口模块的编译配置
│ └── hvigorfile.ts -------------------------------- 入口模块的编译构建任务脚本
├─┬ packages
│ └─┬ xxx_module ---------------------------------------- 功能模块
│ ├─┬ src ------------------------------------------ 模块源码
│ │ └─┬ main
│ │ └── module.json5 ----------------------------- 模块的基本配置
│ ├── build-profile.json5 -------------------------- 模块的编译配置
│ └── hvigorfile.ts -------------------------------- 模块的编译构建任务脚本
├── scripts ------------------------------------------ 辅助脚本
├── hvigor ------------------------------------------- 构建工具
├── build-profile.json5 ------------------------------ 应用级编译配置
└── hvigorfile.ts ------------------------------------ 应用级编译构建任务脚本
- app.json5 应用的全局配置,包含应用的Bundle名称、开发厂商、版本号等基本信息
json5
{
"app": {
"bundleName": "com.xxx.xxx",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}
-
module.json5 各类模块的基本配置
- 基本配置信息,包含Module名称、类型、描述、支持的设备类型等基本信息,使用模块的时候的模块
- 应用组件信息,包含UIAbility组件和ExtensionAbility组件的描述信息,主要在 abilities 中进行配置,当类型为 entry 时进行配置,用于配置启动应用的相关配置
- 应用运行需要的权限信息,主要在配置中的requestPermissions 中进行配置,如网络模块可能需要网络权限
页面路由
页面路由有以下两种类型
路由
若创建的是 shared 模块,可在 main/module.json5 中配置 pages 的位置,$profile 对应的地址就是模块中的 resources/base/profile
鸿蒙中的页面在每个模块的 main/ets/pages 文件夹中,同比配置页面路由的地方在由上方配置的resources/base/profile/main-pages.json 中
以上就有点类似于小程序里的pages和app.json里配置的 pages了,在页面中进行路由跳转也有系统提供的 router模块,使用对应的api进行跳转即可,比如下面这样
调纯页面样式的话可以直接使用 ide 的 previewer 功能,不需要使用模拟器,若需要其他操作的话则需要额外开启模拟器
命名路由
有些时候创建的是 har 模块,这种模块中的模块配置中无法配置 pages,此时则可以通过创建命名路由的方式进行路由页面创建。
使用时则通过调用 router 的 pushNamedRoute 或 replaceNamedRoute 来进行跳转即可
ArkTs
router.pushNamedRoute({
name: 'gmu_file_test_page',
params: new routerParams('message' ,[123,456,789])
}, (err) => {
if (err) {
console.error(`pushNamedRoute failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('pushNamedRoute success');
})
这种命名路由有点类似于如 vue 项目中,在某个组件中通过 addRoute 来动态添加路由,供后续进行访问。
打包依赖安装 - ohpm
鸿蒙里的各个模块的依赖都在 oh-package.json5 中的 devDependencies 进行配置,打包时通过 ohpm 进行依赖的安装。类比于前端框架里的 package.json 和 npm 依赖安装。安装完成后和 package.json 一样,会生成一个对应的 lock 文件
模块使用
在鸿蒙里的模块引用与导出,类似于前端的 esm 中的 import 、export
比如系统文件模块的引用:
javascript
import fs from '@ohos.file.fs';
比如类的导出
typescript
export class GlobalContext {
private constructor() {
}
private static instance: GlobalContext;
private objects = new Map<string, Object>();
...
}
总结
在开发适配鸿蒙系统的功能时,主要采用了基于 TypeScript 的 ArkTs 开发语言。ArkTs 作为基于 TypeScript 的语言,为我们前端开发者提供了熟悉的编程环境,为前端开发人员进入鸿蒙系统应用开发带提供了便利。使前端开发者向终端领域扩展能够相对轻松。
最后
除了开发工具对设备有要求,开发运行内存还占了10个g,有需求的赶紧更新下设备🍜