从零到一:用仓颉语言打造你的第一个鸿蒙应用

引言 💡
仓颉作为华为推出的下一代编程语言,与鸿蒙操作系统深度融合。相比JavaScript(ArkTS),仓颉提供了更强大的类型系统、更优的性能和更直观的开发体验。
一、开发环境搭建 🛠️
1.1 必备工具链
安装步骤:
-  DevEco Studio 配置 - 下载最新版DevEco Studio(支持仓颉插件)
- 安装仓颉语言支持插件
- 配置鸿蒙SDK和NDK路径
 
-  仓颉编译器 # macOS/Linux curl -sSL https://repo.harmonyos.com/cj/install.sh | bash# 验证安装 cjc --version
-  鸿蒙应用框架 - HarmonyOS API 版本:API 11+
- 仓颉版本:1.0+
 
1.2 项目结构规范
MyHarmonyApp/
├── src/
│   ├── main/
│   │   ├── ets/               # 仓颉源码目录
│   │   │   ├── pages/         # 页面组件
│   │   │   ├── common/        # 公共模块
│   │   │   └── MainAbility.cj # 入口
│   │   ├── resources/         # 资源文件
│   │   └── module.json5       # 模块配置
├── build-profile.json5
└── hvigorfile.ts
二、核心语言特性速览 📚
2.1 与ArkTS的主要区别
| 特性 | 仓颉 | ArkTS | 
|---|---|---|
| 类型系统 | 强类型,编译期检查 | 可选类型注解 | 
| 性能 | 接近C++,原生编译 | 解释执行 | 
| 包管理 | 原生支持 | 第三方方案 | 
| 并发模型 | 协程+Actor | 异步+Promise | 
2.2 基础语法要点
变量声明:
// 类型推导
var name = "鸿蒙应用"
let count: Int64 = 100// 常量必须初始化
let MAX_SIZE: Int64 = 1024
函数定义:
// 标准函数
func calculateSum(a: Int64, b: Int64): Int64 {return a + b
}// Lambda 表达式
let multiply = |x: Int64, y: Int64| { x * y }
类与接口:
public class DataModel {private var id: Int64public var name: Stringpublic init(id: Int64, name: String) {this.id = idthis.name = name}
}public interface DataProvider {func fetchData(): Array<DataModel>
}
三、UI开发核心 🎨
3.1 声明式UI框架
仓颉使用与ArkTS类似的声明式UI框架,但语法更简洁:
页面组件基础:
import { Component, State, Build } from '@ohos/ets'@Entry
@Component
public struct HomePage {@State private var count: Int64 = 0@Buildpublic func build() {Column() {Text("计数器应用").fontSize(24).fontWeight(FontWeight.Bold)Text(this.count.toString()).fontSize(48).fontColor(Color.Blue)Button("点击增加").width("80%").height(44).onClick(|| {this.count += 1})}.width("100%").height("100%").justifyContent(FlexAlign.Center)}
}
3.2 状态管理深度解析
@State 装饰器工作原理:
@Component
public struct StateExample {// 状态变化时自动触发UI更新@State private var isVisible: Bool = true@State private var items: ArrayList<String> = ArrayList()// 监听状态变化@Watch("onNameChanged")@State private var userName: String = ""private func onNameChanged() {// 状态变化回调logger.info("用户名已更改: ${this.userName}")}
}
@Prop 双向绑定:
@Component
public struct ParentComponent {@State private var parentValue: String = "初始值"@Buildpublic func build() {Column() {ChildComponent({ value inthis.parentValue = value  // 子组件修改触发父组件更新})}}
}@Component
public struct ChildComponent {private var callback: (String) -> Void@Buildpublic func build() {Button("更新").onClick(|| {this.callback("新值")})}
}
3.3 列表与网格渲染
高性能列表实现:
@Component
public struct ListViewComponent {@State private var dataList: ArrayList<ListItem> = ArrayList()@Buildpublic func build() {List() {ForEach(this.dataList) { (item: ListItem) inListItemComponent({ item: item }).swipeAction({SwipeAction().delete({// 删除逻辑this.dataList.remove(item)})})}}.width("100%").height("100%").divider({ strokeWidth: 1, color: Color.Gray }).edgeEffect(EdgeEffect.Spring)  // 边界弹簧效果}
}
四、数据持久化与存储 💾
4.1 偏好设置(Preferences)
轻量化配置存储:
import { Preferences } from '@ohos.data.preferences'public class PreferencesHelper {private var preferences: Preferences?public func init() {do {this.preferences = try Preferences.getPreferences(context: AppContext.getInstance(),name: "app_prefs")} catch (e: Exception) {logger.error("初始化Preferences失败: ${e.message}")}}public func saveString(key: String, value: String) {do {try this.preferences?.put(key: key, value: value)try this.preferences?.flush()} catch (e: Exception) {logger.error("保存数据失败")}}public func getString(key: String, defaultValue: String = ""): String {do {return try this.preferences?.get(key: key, defaultValue: defaultValue) ?? defaultValue} catch (e: Exception) {return defaultValue}}
}
4.2 关系型数据库(RDB)
数据库操作示例:
import { relationalStore } from '@ohos.data.relationalStore'public class UserDatabase {private var rdbStore: RDBStore?private let DB_NAME = "user_db"private let TABLE_NAME = "users"public func createTable() {let createTableSql = """CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,email TEXT UNIQUE,created_at INTEGER)"""do {try this.rdbStore?.executeSql(createTableSql)} catch (e: Exception) {logger.error("创建表失败: ${e.message}")}}public func insertUser(user: User): Int64 {let values = ValuesBucket()values.putString("name", user.name)values.putString("email", user.email)values.putLong("created_at", Date().getTime())do {return try this.rdbStore?.insert(table: TABLE_NAME,values: values) ?? -1} catch (e: Exception) {logger.error("插入用户失败")return -1}}public func queryUsers(): ArrayList<User> {let users = ArrayList<User>()do {let resultSet = try this.rdbStore?.query(distinct: false,table: TABLE_NAME,columns: ["id", "name", "email"],where: null,whereArgs: null,groupBy: null,having: null,orderBy: "id DESC")while (resultSet?.next() ?? false) {let user = User(id: resultSet!.getLong(0),name: resultSet!.getString(1),email: resultSet!.getString(2))users.add(user)}resultSet?.close()} catch (e: Exception) {logger.error("查询失败")}return users}
}
五、网络通信 🌐
5.1 HTTP 请求封装
现代化HTTP客户端:
import { http } from '@ohos.net.http'public class HttpClient {public static func get(url: String): Future<String> {return Future() { (resolve, reject) indo {let httpRequest = http.createHttpRequest()httpRequest.request(method: http.RequestMethod.GET,url: url,expect: http.HttpDataType.String) { (err, data) inif (err == null) {resolve(data as! String)} else {reject(err!)}}} catch (e: Exception) {reject(e)}}}public static func post(url: String,body: Dictionary<String, Any>): Future<String> {return Future() { (resolve, reject) indo {let httpRequest = http.createHttpRequest()let jsonString = JSON.stringify(body)httpRequest.request(method: http.RequestMethod.POST,url: url,expect: http.HttpDataType.String,data: jsonString) { (err, data) inif (err == null) {resolve(data as! String)} else {reject(err!)}}} catch (e: Exception) {reject(e)}}}
}
5.2 异步调用处理
Future + async/await 组合:
@Component
public struct NetworkComponent {@State private var userData: UserData? = null@State private var isLoading: Bool = falseprivate func fetchUserData(userId: Int64) {this.isLoading = trueasync {do {let response = try await HttpClient.get("https://api.example.com/users/\(userId)")let user = JSON.parse(response) as UserDatathis.userData = user} catch (e: Exception) {logger.error("获取用户数据失败: ${e.message}")} finally {this.isLoading = false}}}
}
六、权限与系统集成 🔐
6.1 权限声明与申请
模块配置文件:
// module.json5
{"module": {"name": "entry","type": "entry","requestPermissions": [{"name": "ohos.permission.CAMERA","usageScene": {"ability": ["com.example.myapp.MainAbility"],"when": "inuse"}},{"name": "ohos.permission.READ_MEDIA","usageScene": {"ability": ["com.example.myapp.MainAbility"],"when": "inuse"}}]}
}
6.2 运行时权限申请
import { abilityAccessCtrl } from '@ohos.abilityAccessCtrl'public class PermissionManager {public static func requestPermissions(permissions: ArrayList<String>): Future<Bool> {return Future() { (resolve, reject) inlet atManager = abilityAccessCtrl.createAtManager()atManager.requestPermissionsFromUser(permissions: permissions) { (err, grantStatus) inif (err == null) {let allGranted = grantStatus.every { |status| status == 0 }resolve(allGranted)} else {reject(err!)}}}}public static func checkPermission(permission: String): Bool {let atManager = abilityAccessCtrl.createAtManager()return atManager.checkAccessToken(permission) == 0}
}
七、性能优化要点 ⚡
7.1 常见性能陷阱
避免频繁重建组件:
// ❌ 错误:每次状态更新都重建
@Component
public struct BadExample {@State private var count: Int64 = 0@Buildpublic func build() {Column() {ForEach(Array(0..<this.count)) { (i: Int64) in// 这会在count改变时全部重建Text("Item \(i)")}}}
}// ✅ 正确:使用@ItemProvider优化
@Component
public struct GoodExample {@State private var items: ArrayList<String> = ArrayList()@Buildpublic func build() {List() {ForEach(this.items) { (item: String) inText(item).height(50)}}}
}
7.2 内存管理最佳实践
@Component
public struct MemoryOptimized {@State private var largeData: ArrayList<Data>? = nullpublic func onDestroy() {// 清理大对象引用this.largeData = null}private func processData() {// 使用本地作用域,及时释放do {let tempBuffer = ArrayList<Data>()// 处理逻辑tempBuffer.clear()}// tempBuffer 在此自动释放}
}
八、完整示例项目 📱
简单的待办事项应用(TODO App)框架:
import { Component, State, Build, Entry } from '@ohos.ets'public struct TodoItem {public let id: Int64public var title: Stringpublic var isDone: Boolpublic let createdAt: Int64
}@Entry
@Component
public struct TodoApp {@State private var todos: ArrayList<TodoItem> = ArrayList()@State private var inputValue: String = ""@State private var nextId: Int64 = 1private func addTodo() {if (this.inputValue.isEmpty()) returnlet newTodo = TodoItem(id: this.nextId,title: this.inputValue,isDone: false,createdAt: Date().getTime())this.todos.add(newTodo)this.nextId += 1this.inputValue = ""}private func toggleTodo(id: Int64) {for (i in 0..<this.todos.size()) {if (this.todos.get(i).id == id) {this.todos.get(i).isDone = !this.todos.get(i).isDonebreak}}}private func deleteTodo(id: Int64) {this.todos.removeIf { |todo| todo.id == id }}@Buildpublic func build() {Column() {// 顶部Row() {Text("我的待办").fontSize(24).fontWeight(FontWeight.Bold)}.width("100%").height(60).padding({ left: 16, right: 16 })// 输入框Row() {TextInput({ placeholder: "输入新任务" }).value(this.inputValue).onChange { |value| this.inputValue = value }.layoutWeight(1)Button("添加").width(60).onClick(|| { this.addTodo() })}.width("100%").height(50).padding({ left: 16, right: 16, top: 8, bottom: 8 })// 待办列表List() {ForEach(this.todos) { (todo: TodoItem) inListItem() {Row() {Checkbox().select(todo.isDone).onChange(|| { this.toggleTodo(todo.id) })Text(todo.title).layoutWeight(1).decoration(todo.isDone ? TextDecoration.LineThrough : TextDecoration.None)Button("删除").type(ButtonType.Capsule).height(30).onClick(|| { this.deleteTodo(todo.id) })}.width("100%").padding(12)}}}.width("100%").layoutWeight(1)}.width("100%").height("100%")}
}
九、调试与测试 🧪
9.1 本地调试技巧
# 编译并运行
cjc build --debug# 连接设备
hdc list targets# 安装应用
hdc install app-debug.hap# 查看日志
hdc shell hilog
9.2 单元测试编写
import { Test, TestSuite } from '@ohos.test'@TestSuite
public class CalculatorTests {@Testpublic func testAddition() {let calc = Calculator()let result = calc.add(2, 3)assert(result == 5, "2 + 3 应该等于 5")}@Testpublic func testDivisionByZero() {let calc = Calculator()assertThrows {calc.divide(10, 0)}}
}
十、总结与建议 🎯
核心要点回顾:
✅ 仓颉相比ArkTS提供更强的类型系统和性能
 ✅ 声明式UI编程模型与ArkTS类似但语法更简洁
 ✅ 充分利用@State等装饰器实现响应式更新
 ✅ 合理使用数据库和缓存策略优化应用性能
 ✅ 重视权限申请和用户隐私保护
推荐资源 🔗:
- 官方文档:https://developer.harmonyos.com
- 仓颉语言指南:HarmonyOS官方教程
- 社区论坛:HarmonyOS开发者社区
- 示例项目:GitHub HarmonyOS应用库
