普通视图
HarmonyOS Next 端云一体化(3)
HarmonyOS Next 端云一体化(3)
上一章我们主要讲解了如何新建数据库、新建数据表已经部署数据库。这一章主要学习如何对数据库、数据表进行 CRUD 的操作。
操作数据库的方式
我们操作数据库的方式一共有 4 种。
- 可视化 - AGC 平台上直接编辑数据
- 可视化 - DevEco Studio 中直接编辑数据
- 编程 - 客户端通过代码的方式操作数据
- 编程 - 云函数通过代码的方式操作数据
方式 1、2 都是为了让开发人员简单、方便管理数据。但是实际的业务场景中,我们更多要关注的是 3、4 的方式。那么本章主要讲的是 方式 3-客户端通过代码的方式操作数据 。后续再讲到云函数的时候再来补充方式 4。
生成客户端-数据模型
先解释下这个功能是做什么的。因为我们的目标是要在 客户端来查询数据库的数据,那必不可少需要在客户端中定义数据表实体的类型。然后 DevEco Studio 提供了比较便捷的根据数据实体生成客户端-数据模型。
我这里红色的提示是因为我之前已经生成过了,所以提示是否覆盖。
成功后边得到如下内容:entry/src/main/ets/common/types/Book.ts
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
* Generated by the CloudDB ObjectType compiler. DO NOT EDIT!
*/
import { cloudDatabase } from "@kit.CloudFoundationKit";
class Book extends cloudDatabase.DatabaseObject {
id: number;
name: string;
price: number;
publish: Date;
hot: boolean;
cover: string;
naturalbase_ClassName(): string {
return "Book";
}
}
export { Book };
简单使用
接下来我们就可以进入客户端查询数据库的步骤了。
- 首先我们需要创建一个数据库示例,每一个存储区就是一个数据库
cloudDatabase.DatabaseZone
- 然后指定查询条件,比如全部查询、查询 id 等于 1 等等
condition
- 进行查询,接收返回的数据
import { cloudDatabase } from '@kit.CloudFoundationKit';
import { Book } from '../common/types/Book';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct PageDB {
// 数据库实例,初始化时为 undefined
agcDataBase: cloudDatabase.DatabaseZone | undefined = undefined;
// 查询条件实例,初始化时为 undefined
condition: cloudDatabase.DatabaseQuery<cloudDatabase.DatabaseObject> | undefined = undefined;
// 初始化数据库连接的方法
fn1 = () => {
this.agcDataBase = cloudDatabase.zone('Study');
promptAction.showToast({ message: `初始化成功` });
}
// 查询数据库的方法
fn2 = async () => {
try {
// 创建查询条件实例
this.condition = new cloudDatabase.DatabaseQuery(Book);
// 设置查询结果的最大数量为 10
this.condition.limit(10);
// 执行查询并获取结果
const resultArray = await this.agcDataBase?.query(this.condition);
// 显示查询结果
AlertDialog.show({ message: JSON.stringify(resultArray, null, 2) });
} catch (e) {
promptAction.showToast({ message: `${e.message} ${e.code}` });
console.error(e.message, e.code);
}
}
build() {
Column({ space: 10 }) {
Button("初始化1")
.onClick(this.fn1)
Button("查询2")
.onClick(this.fn2)
}
.height('100%')
.width('100%')
}
}
对数据表的操作
端云一体提供了基本的对数据表的操作。主要分成以下几种
操作类型 | 说明 |
---|---|
query | 查询 |
upsert | 新增或者编辑 |
delete | 删除 |
calculateQuery | 计算 |
query
就是查询,上面的示例中已经使用过了。
upsert - 新增
现在主要演示 使用 upsert 实现新增
upsert 方法可以接收一个或者多个数据实体。如果该数据之前不存在,这时的 upsert 表示新增,反之表示更新。
操作成功后,会返回成功影响了的数据的数量。
比如新增:
fn3 = async () => {
try {
const book = new Book();
book.id = parseInt(Date.now().toString().slice(0, 6)); // 正常应该是自增的,但是这个自增会出bug
book.name = "book";
book.price = 99;
book.publish = new Date();
book.hot = true;
book.cover = "xxxx";
const res = await this.agcDataBase?.upsert(book);
AlertDialog.show({ message: `新增成了${res}条` });
} catch (e) {
promptAction.showToast({ message: `${e.message} ${e.code}` });
console.error(e.message, e.code);
}
};
Button("新增3").onClick(this.fn3);
需要注意的是:我们当前的角色是 World
,此时是没有 新增、编辑、删除权限的。所以为了方便操作,可以修改调整权限
clouddb/objecttype/Book.json
{
"role": "World",
"rights": [
"Read",
"Upsert",
"Delete"
]
},
当数据表信息发生了修改时,需要在 AGC 平台上删除之前的数据区+数据表。然后重新部署。
upsert - 编辑
这里我们可以根据 id 来编辑一下数据。 数据库里面存放着id:10 的数据,我们就来修改它。
fn4 = async () => {
try {
const book = new Book();
// 固定修改id为10的数据
book.id = 10;
book.name = "更新book";
book.price = 999;
book.publish = new Date();
book.hot = true;
book.cover = "更新 xxxx";
const res = await this.agcDataBase?.upsert(book); // 因为数据 id已经存在,所以此时是编辑
AlertDialog.show({ message: `编辑成功${res}条` });
} catch (e) {
promptAction.showToast({ message: `${e.message} ${e.code}` });
console.error(e.message, e.code);
}
};
Button("更新4").onClick(this.fn4);
delete - 删除
执行删除 delete 方法时,也是需要传入一个或者多个删除的元素。
我们这里就可以根据 id:10 的元素执行删除。
fn5 = async () => {
try {
const book = new Book();
// 固定修改id为10的数据
book.id = 10;
const res = await this.agcDataBase?.delete(book); // 因为数据 id已经存在,所以此时是编辑
AlertDialog.show({ message: `删除成功${res}条` });
} catch (e) {
promptAction.showToast({ message: `${e.message} ${e.code}` });
console.error(e.message, e.code);
}
};
Button("删除5").onClick(this.fn5);
calculateQuery - 计算
calculateQuery
从数据库中查询符合条件的数据,并对指定字段进行算术计算。主要提供了以下的计算功能。
名称 | 值 | 说明 |
---|---|---|
AVERAGE | 0 | 计算平均数。 |
SUM | 1 | 计算总和。 |
MAXIMUM | 2 | 计算最大值。 |
MINIMUM | 3 | 计算最小值。 |
COUNT | 4 | 计算记录总数。 |
fn6 = async () => {
try {
// 创建查询条件实例
this.condition = new cloudDatabase.DatabaseQuery(Book);
// 设置查询结果的最大数量为 10
this.condition.limit(10);
// 执行查询并获取结果
const resultArray = await this.agcDataBase?.calculateQuery(
this.condition,
"price",
cloudDatabase.QueryCalculate.SUM
);
// 显示查询结果
AlertDialog.show({ message: JSON.stringify(resultArray, null, 2) });
} catch (e) {
promptAction.showToast({ message: `${e.message} ${e.code}` });
console.error(e.message, e.code);
}
};
Button("计算6 总价格").onClick(this.fn6);
总结
本章主要介绍了在 HarmonyOS Next 中如何通过客户端代码操作云数据库,主要包含以下几个要点:
- 操作数据库的四种方式,重点介绍了客户端代码操作方式
- 使用 DevEco Studio 自动生成客户端数据模型,简化开发流程
- 详细讲解了数据库的基本操作:
- 初始化数据库连接(DatabaseZone)
- 查询数据(query)
- 新增/更新数据(upsert)
- 删除数据(delete)
- 数据计算(calculateQuery)
- 介绍了各种操作的参数说明和返回值,并提供了完整的示例代码
以上是对客户端操作数据库的基本功能演示。下一章会重点来讲解查询语法。condition。
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。
HarmonyOS Next 端云一体化(2)
HarmonyOS Next 端云一体化(2)
本章节主要讲一下端云一体化中的数据库操作
介绍
云数据库是端云协同的数据库产品,具备端云数据协同管理、统一数据模型及丰富数据管理 API 接口等能力。它采用基于对象模型 的
数据存储结构,数据以对象(Object) 形式存于不同存储区,每个对象为一条完整数据记录。 对象类型(ObjectType) 定义存储对
象集合,不同对象类型对应不同数据结构。存储区(Zone) 是独立的数据存储区域,每个存储区的对象类型定义完全相同。
学习流程
我们会按照以下流程来进行学习。
- 新建存储区:也就是新建数据库
- 创建对象类型:创建一个用于存储数据条目的对象类型。
- 添加数据条目:在刚刚创建的对象类型内添加一条条数据,并配置数据所在的存储区。
- 部署云数据库:数据成功添加后,您可以直接将该数据部署至 AGC 云端。您也可以等所有对象类型和数据条目开发完成后,再统一批量部署到 AGC 云端。
存储区
我们这里新建一个存储区 Study 用来存放稍后用到的数据。
然后我们在 DevEco Studio 的 云端配置中指定存储区。
clouddb/db-config.json
{
"defaultCloudDBZoneName": "Study", // 存储区的名称
"defaultDataStorageLocation": "CN"
}
创建对象类型
什么是创建对象类型
创建对象类型可以理解为就是为我们的数据定义类型。类似于使用接口或者 class 来定义数据,但是这里操作的范围要更大。
- 定义基本的数据类型,如数字、字符串、布尔、日期时间等。
- 定义字段的权限,因为这个对象类型本身是数据表,定义权限相当于设置了哪一类用户拥有哪些权限。如读取、编辑、新增、删除等
- 定义索引,考虑数据量大需要比较方便的查找到要操作的数据,需要定义索引。
比如,我们需要根据书籍数据来定义类型。 Book
字段 | 类型 | 说明 |
---|---|---|
id | number | id |
name | string | 书名 |
price | number | 价格 |
publish | date | 出版日期 |
hot | boolean | 是否热门 |
cover | string | 封面 |
对象类型的规范
新建 Book 对象类型文件
这个对文件需要按照以下格式来编写。其中的字段的一些规范需要特别注意。
{
"objectTypeName": 对象实体名称
"fields": 对象中的属性
"indexes": 索引
"permissions" 权限
}
objectTypeName
表示实体对象的名称,我们这里可以是 Book
{
"objectTypeName": "Book"
}
fields
fields 表示这个对象中属性的一些规则。
参数 | 必选(M)/可选(O) | 说明 |
---|---|---|
fieldName | M | 字段名称。输入要求具体如下:字段的名称长度必须大于或等于 1 个字符,小于或等于 30 个字符,只能包含以下 3 种类型,并且至少包含“字母”类型:字母(A-Z 或 a-z)数字(0-9)特殊字符:_字段名称必须以字母开头,以字母或者数字结尾。字段名称中不区分字母的大小写。修改对象类型时,支持删除字段。字段名称不允许使用系统保留字段名称: naturalbase_version、naturalbase_deleted、naturalbase_operationtype、naturalbase_creator、naturalbase_accesstime、naturalbase_operationtime、naturalbase_syncstatus、naturalbase_changedfieldsbitmap、naturalbase_lastmodifier、cmin、cmax、xmin、xmax、ctid、oid、tableoid、xc_node_id、tablebucketid、rowid。说明当前 Cloud Foundation Kit 暂不支持自增类型字段 IntAutoIncrement 或 LongAutoIncrement。 |
fieldType | M | 字段的数据类型。当前支持的数据类型:String、Boolean、Byte、Short、Integer、Long、Float、Double、ByteArray、Text、Date、IntAutoIncrement(数字-自增) |
belongPrimaryKey | O | 设置该字段是否为对象类型的主键,默认值为 false。至少设置一个字段为主键。支持设置复合主键,由多个字段组合成为主键,一个复合主键包含的字段小于等于 5 个,复合主键字段顺序与字段的顺序一致。数据类型为 ByteArray、Text、Date、Double、Float 和 Boolean 的字段不支持设置为主键。主键的值不允许更改。 |
notNull | O | 设置字段值是否为非空,默认值为 false。数据类型为 ByteArray 和 Date 的字段不支持设置为非空。主键默认非空,且不允许更改。设置为非空的字段不支持加密和敏感。 |
isNeedEncrypt | O | 设置字段是否需要加密,开启全程加密数据管理功能,默认值为 false。选择加密后,该字段对应的数据会加密存储在存储区中。主键字段不支持加密。加密的字段不支持设置为非空。加密的字段不支持设置为敏感字段。一个对象类型中包含的加密字段和敏感字段的总数需小于或等于 5 个。字段设置为加密后,不支持导出该字段的数据值。数据类型为 ByteArray、Text 的字段不支持加密。对象类型创建成功后,不支持修改加密属性。 |
isSensitive | O | 设置字段是否为敏感字段,默认值为 false。选择敏感后,该字段对应的数据会加密存储在存储区中。敏感字段不支持设置为主键。敏感字段不支持设置为非空。敏感字段不支持设置为加密。敏感字段不支持设置为默认值。对象类型创建成功后,不支持修改敏感属性。仅支持数据类型为 Byte、Short、Integer、Long、Float、Double、String 和 Date 的字段设置为敏感字段。敏感字段不支持设置为索引。一个对象类型中包含的加密字段和敏感字段的总数需小于或等于 5 个。 |
defaultValue | O | 字段为非空时,必须设置默认值。主键不支持设置默认值。加密字段和敏感字段不支持设置默认值。数据类型为 ByteArray、Date 不支持为其设置默认值。数据类型为 Text 的字段设置默认值时,默认值的长度小于或等于 200 个字符。 |
按照我们想要的书籍的规定。可以这样
fieldName | fieldType | belongPrimaryKey |
---|---|---|
id | IntAutoIncrement | true |
name | String | - |
price | Double | - |
publish | Date | - |
hot | Boolean | - |
cover | String | - |
{
"objectTypeName": "Book",
"fields": [
{
"fieldName": "id",
"fieldType": "IntAutoIncrement",
"belongPrimaryKey": true,
"notNull": true
},
{
"fieldName": "name",
"fieldType": "String"
},
{
"fieldName": "price",
"fieldType": "Double"
},
{
"fieldName": "publish",
"fieldType": "Date"
},
{
"fieldName": "hot",
"fieldType": "Boolean"
},
{
"fieldName": "cover",
"fieldType": "String"
}
]
}
indexes
在indexes中为该对象类型配置索引、索引包含的字段、以及索引包含的字段的排序方式。
参数 | 必选(M)/可选(O) | 说明 |
---|---|---|
indexName | M | 索引名称。输入要求具体如下:索引的名称长度必须大于或等于 1 个字符,小于或等于 30 个字符,只能包含以下 3 种类型,并且至少包含“字母”类型:字母(A-Z 或 a-z)数字(0-9)特殊字符:_索引名称必须以字母开头。索引名称中不区分字母的大小写。修改对象类型时,仅支持新增或者删除索引。当删除索引后,本次提交前不允许新增同名索引。每个对象类型可以设置小于或等于 16 个索引。数据类型为 ByteArray 和 Text 的字段不支持设置为索引。 |
indexList > fieldName | M | 索引包含的字段。支持设置组合索引,由多个字段组合成为索引,一个组合索引包含的字段不超过 5 个。 |
indexList > sortType | M | 索引包含的字段的排序方式,支持 ASC 升序或 DESC 降序。 |
这里我们为书籍的 id 和书籍的名称提供索引。
{
"indexes": [
{
"indexName": "id_Index",
"indexList": [
{
"fieldName": "id",
"sortType": "ASC"
}
]
},
{
"indexName": "price_Index",
"indexList": [
{
"fieldName": "price",
"sortType": "DESC"
}
]
}
]
}
permissions
permissions 字段用来设置该数据表的操作权限的。
目前提供的角色和权限有以下分类。
参数 | 必选(M)/可选(O) | 说明 |
---|---|---|
role | M | 用户角色,包括:World:代表所有用户,包含认证和非认证用户。该角色默认拥有 Read 权限,可自定义配置 Upsert 和 Delete 权限。但是,不建议将 Upsert 和 Delete 权限配置给所有人角色。当对象类型中设置了加密字段之后,表示开启全程加密功能,此时所有人角色将不会拥有 Read、Upsert 和 Delete 权限,且不允许修改。Authenticated:经过 AGC 登录认证的用户。该角色默认拥有 Read 权限,可自定义配置 Upsert 和 Delete 权限。当对象类型中设置了加密字段之后,表示开启全程加密功能,此时认证用户角色将不会拥有 Read、Upsert 和 Delete 权限,且不允许修改。Creator:经过认证的数据创建用户。该角色默认拥有所有权限,且可自定义配置所有权限。每条数据都有其对应的数据创建人(即应用用户),每个数据创建者仅可以 Upsert 或者 Delete 自己创建的数据,不能 Upsert 或者 Delete 他人创建的数据。数据创建者的信息保存在数据记录的系统表中。Administrator:应用开发者,主要是指通过 AGC 控制台或 FaaS(Function as a Service,函数即服务)侧访问云数据库的角色。该角色默认拥有所有权限,且可自定义配置所有权限。Administrator 可以管理并配置其他角色的权限。 |
rights | M | 授予角色的权限,包括 Read、Upsert(包含新增和修改)和 Delete 权限。 |
接下来,我们为 这些角色设置以下的权限。
角色 | Read | Upsert | Delete |
---|---|---|---|
World | √ | – | – |
Authenticated | √ | √ | – |
Creator | √ | √ | √ |
Administrator | √ | √ | √ |
代码如下:
{
"permissions": [
{
"role": "World",
"rights": ["Read"]
},
{
"role": "Authenticated",
"rights": ["Read", "Upsert"]
},
{
"role": "Creator",
"rights": ["Read", "Upsert", "Delete"]
},
{
"role": "Administrator",
"rights": ["Read", "Upsert", "Delete"]
}
]
}
创建数据条目
我们搭建好了对象类型,现在可以根据它来插入数据了。
-
新建数据文件
-
插入数据 这里可以看到一些基本数据
{ "cloudDBZoneName": "Study", "objectTypeName": "Book", "objects": [ { "id": 1, "name": "string1", "price": 10.5, "publish": 1737014949576, "hot": true, "cover": "string1" }, { "id": 2, "name": "string2", "price": 20.5, "publish": 1737014949576, "hot": false, "cover": "string2" } ] }
字段解释
- cloudDBZoneName:配置存储区名称。
- objects:配置当前对象类型中所有字段的值,即写入数据。一个对象(object)即为一条数据,您可以通过新建一个对象(object)来为字段赋新值,也可以修改某个对象(object)下字段的值(主键或加密字段的值不支持修改)
部署云数据库
刚才我们都是在本地搭建的数据库,现在我们需要将这些数据同步到 AGC 平台的数据库上。
部署的方式也很简单
- 部署
- 成本
-
刷新 AGC 平台上的数据库
总结
本文详细介绍了 HarmonyOS 云数据库的基本操作流程:
-
存储区(Zone)创建
- 创建名为 Study 的存储区
- 在 DevEco Studio 中配置存储区信息
-
对象类型(ObjectType)定义
- 详细讲解了对象类型的规范和组成部分
- 包含 objectTypeName、fields、indexes 和 permissions 四个主要部分
- 以 Book 对象为例,展示了完整的对象类型定义过程
-
数据操作
- 创建数据条目的具体步骤
- 展示了如何在 JSON 文件中定义数据内容
- 说明了 cloudDBZoneName 和 objects 的配置方法
-
云端部署
- 介绍了如何将本地数据库部署到 AGC 平台
- 展示了部署过程和成本预估
- 说明了如何在 AGC 平台上刷新数据库
通过这些步骤,我们完成了一个基本的云数据库的创建、配置和部署过程,为后续的端云协同开发打下了基础。
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。
HarmonyOSNext 端云一体化(1)
HarmonyOSNext 端云一体化(1)
Cloud Foundation Kit(云开发服务)可以按需为应用提供云函数、云数据库、云存储等云端服务。应用运行所需的服务器和环境可以皆由云端平台提供,开发者只需关注应用的业务逻辑,而无需关心基础设施(例如:服务器、操作系统、容器等)。
DevEco Studio 中还提供了端云一体化开发的开发体验,您可以基于统一的技术栈,高效、协同地完成端、云代码的编写、调试、编译和部署,极大提高构建 HarmonyOS 应用和元服务的效率。
应用场景
- 应用后端 快速构建应用或者元服务的后端服务,从而大幅简化应用开发与运维相关的事务,快速完成应用的构建
- 计算密集型任务 当应用中出现计算密集型任务时,可以在云端及时申请足够的算力来支撑任务的执行。当任务结束时,可以立即释放资源,避免浪费。****
- 适配类应用 通过 Cloud Foundation Kit 实现协议类型的转换,比如实现 IoT 中不同设备的协议适配。以及接入第三方平台,通过第三方平台提供的接口,实现业务的接入或者协作。
- 突发大量访问 传统架构服务在某些特殊场景下,可能出现大量的访问。为保证业务高峰时,系统能稳定运行,一般需要购买高性能、昂贵的服务器,组建集群负载均衡。但是,当业务回落时,就导致了大量服务器的资源浪费。
包含的资源
端云一体主要包含的资源有
- 云函数
- 云数据库
- 云存储
适配的项目类型
端云一体可以用在开发鸿蒙的应用或者是元服务上。因为考虑应用的上架需要软著+备案,而元服务的上架只需要备案。所以后续的教程中为了更加方便学习,我们会在元服务的环境下进行。
学习流程
稍后我们会延续着以下步骤,让大家可以尽可能的掌握端云一体的开发流程。
- AGC 平台新建元服务
- DevEco Studio 新建对应的项目工程
- 云函数的基本使用
- 云数据库的基本使用
- 云存储的基本使用
AGC 平台新建元服务
在 AGC 平台上新建服务的具体步骤可以参考这个文章 HarmonyOS Next 最新 元服务新建到上架全流程,这里就不再叙述了。
DevEco Studio 新建对应的项目工程
本地在使用 DevEco Studio 新建工程时,需要新建的是端云一体化的元服务项目。
此时,你的项目中会看到额外的云端相关的目录结构。
特别需要注意的是,目前模拟器是不支持运行端云一体的项目的。所以为了方便测试,最好是具体真机。
运行到真机
- 测试下云函数
-
测试下云数据库
还没有在云端配置云数据库,所以此时的测试是没有反应的。
-
测试下云存储
云端环境一览
我们需要知道的是,在本地操作云端的资源时,本质上都是对云端的资源的一些操作。最终的操作成功与否,都会反映到真正的云端环境。
我们登录 AGC 平台,然后找到对应的项目。这里是元服务的名称,不是项目的名称,你的元服务是归属于某个项目的
云函数一览
云函数其实就是存放后端逻辑的部分。也是我们后期编写后端业务主要区域。
云数据库一览
这里的字段解释如下
字段 | 说明 |
---|---|
对象类型 | 表示你的数据中用到的实体的类型,比如用户、购物车都是不同的实体类型,也可以理解为你的数据表格 |
存储区 | 理解为数据库的名称,你可以在这里管理多个存储区-数据库 |
数据 | 你存储的实际的数据 |
-
对象类型
-
存储区
-
数据
云存储一览
云存储就是存放你物理文件的地方,比如图片、视频、音频等等。
DevEco Studio 中的云端资源
小伙伴们应该还记得,我们在新建端云一体云服务的时候,本地工程中也是多了一个文件夹的。 CloudProgram
它里面的主要目录结构如下。
- clouddb 存放数据库相关的文件
- cloudfunctions 存放云函数相关的文件
- cloud-config.json 存放云端环境相关的配置
后期我们开发的思路可以是以下两种方式:
- 全部都在 AGC 平台上操作,如编写云函数逻辑代码、搭建数据库、数据表
- 尽量都在本地 DevEco Studio 工具中编写云函数逻辑代码、调试代码、搭建数据库、数据集表
以上两种方式都可以。但是为了刚好的开发体验,我们是建议使用方式 2.
总结
本文介绍了 HarmonyOS Next 中端云一体化开发的基础概念和环境搭建。通过 Cloud Foundation Kit,开发者可以更便捷地使用云函数、云数据库和云存储等云端服务,从而专注于业务逻辑的开发,而无需过多关注基础设施的搭建和维护。
主要内容包括:
- 端云一体化的应用场景和主要资源
- AGC 平台上创建元服务的流程
- DevEco Studio 中创建端云一体化项目的步骤
- 云端环境(云函数、云数据库、云存储)的基本介绍
- 本地开发环境的目录结构和开发方式建议
通过本文的学习,读者可以对 HarmonyOS Next 的端云一体化开发有一个整体的认识,为后续深入学习打下基础。建议开发者优先选
择在 DevEco Studio 中进行开发,这样可以获得更好的开发体验。
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。