领取优惠


背景痛点:毕设≠玩具项目

高校里做鸿蒙毕设,最容易掉进“Demo 级”陷阱:把所有逻辑塞进一个 Pages 目录,Ability 生命周期靠 onPageShow 硬凑,配置信息直接写死在 config.json,结果一跑真机就内存抖动、权限弹窗连环轰炸。评委老师一句“工程化程度不足”便让辛苦三个月的代码瞬间贬值。痛点归纳起来无非三点:

  1. 无架构:业务、数据、UI 三层揉成一团,后期加功能就“牵一发动全身”。
  2. 无生命周期管理:Ability 被系统回收后状态丢失,页面返回白屏。
  3. 无安全与性能意识:敏感权限一次性全申请,冷启动耗时 3 s 开外,数据明文落盘。

毕设要“能跑”更要“能演”,必须向生产规范看齐。

技术选型:Stage 模型 + ArkTS 的硬实力

OpenHarmony 4.x 双模型并存,FA(Feature Ability)模型虽兼容旧代码,但粒度粗、跨 Ability 通信依赖 Intent,难以解耦。Stage 模型把 Ability 拆成独立“舞台”,支持 Want 显式跳转、Context 隔离,天然适合模块化。

语言侧,ArkTS 在 TS 基础上引入静态类型强化与并发 Actor 模型,相比 JS 有三点优势:

  • 编译期类型检查,减少运行时崩溃;
  • 装饰器语法原生支持状态管理,无需引入 Redux 等三方库;
  • 并发任务基于 TaskPool,耗时计算不卡主线程。

毕设周期短,选型必须“官方原生 + 文档齐全”,Stage + ArkTS 是当下最优解。

核心实现:状态管理与 Ability 解耦

1. 状态管理方案

采用 @State@Observed@Provide 三层装饰器:

  • @State 标记组件私有状态,驱动 UI 刷新;
  • @Observed 包装对象,深层属性变化可追踪;
  • @Provide 在祖先组件注入,后代通过 @Consume 直接引用,避免逐层传参。

示例:全局用户会话

// UserViewModel.ets
@Observed
export class UserSession {
  userName: string = ''
  token: string = ''
}

// EntryAbility.ets
import { UserSession } from '../viewmodel/UserViewModel'

@Entry
@Component
struct Index {
  @Provide('session') session: UserSession = new UserSession()

  build() {
    Column() {
      if (this.session.userName) {
        MainPage()
      } else {
        LoginPage()
      }
    }
  }
}

2. Ability 间解耦通信

Stage 模型下,UI 与数据服务分置不同 Ability,通过 Want + DataAbilityHelper 解耦:

  • UI Ability 只负责页面渲染,不直接访问数据库;
  • DataAbility 封装 CRUD,对外暴露 URI;
  • 双方通过 helper.call 异步调用,返回 Promise<ResultSet>,实现“视图—数据”完全分离。

示例:查询课程列表

// CourseDataAbility.ets
const COURSE_URI = 'dataability:///com.example.course.DataAbility/course'

export function queryCourses(): Promise<Course[]> {
  let helper = DataAbilityHelper.helper(COURSE_URI)
  return helper.call('query', null, null).then(result => convertResult(result))
}

可运行代码片段:主页面 + 数据服务

以下代码可直接拷贝到 DevEco Studio 4.0 运行,需配套 module.json5 里声明 DataAbility。

// pages/CoursePage.ets
import { queryCourses } from '../data/CourseDataAbility'
import { Course } from '../model/Course'

@Entry
@Component
struct CoursePage {
  @State courseList: Course[] = []

  aboutToAppear() {
    queryCourses().then(list => this.courseList = list)
  }

  build() {
    List({ space: 12 }) {
      ForEach(this.courseList, (item: Course) => {
        ListItem() {
          Row() {
            Text(item.name).fontSize(18)
            Blank()
            Text(`${item.credit}学分`).fontSize(14).opacity(0.6)
          }
          .width('100%')
          .padding(12)
        }
      }, item => item.id.toString())
    }
    .backgroundColor('#F1F3F5')
    .layoutWeight(1)
  }
}
// data/CourseDataAbility.ets
import relationalStore from '@ohos.data.relationalStore'
import { Course } from '../model/Course'

const TABLE_NAME = 'course'
let rdb: relationalStore.RdbStore

export default {
  onCreate(want, callback) {
    const SQL_CREATE = `CREATE TABLE IF NOT EXISTS ${TABLE_NAME}(
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      credit INTEGER)`
    relationalStore.getRdbStore(this.context, { name: 'edu.db' }, (err, store) => {
      if (!err) {
        rdb = store
        rdb.executeSql(SQL_CREATE)
      }
      callback()
    })
  },

  query(uri, columns, predicates) {
    return rdb.query(TABLE_NAME, columns, predicates).then(result => {
      let courses: Course[] = []
      while (result.goToNextRow()) {
        courses.push({
          id: result.getLong(result.getColumnIndex('id')),
          name: result.getString(result.getColumnIndex('name')),
          credit: result.getLong(result.getColumnIndex('credit'))
        })
      }
      result.close()
      return courses
    })
  }
}

关键注释已内嵌,读者可在此基础上继续扩展增删改接口。

性能与安全:冷启动、权限、持久化

  1. 冷启动优化

    • 延迟加载:非首帧必需模块在 aboutToAppear 阶段再拉取;
    • 任务并发:网络请求与数据库初始化放 TaskPool,首页渲染耗时从 1.8 s 降至 0.9 s;
    • 压缩资源:图片统一转 WebP,体积减少 30%。
  2. 敏感权限策略

    • 按场景申请:定位权限只在“校园导航”模块调用前弹窗,拒绝后降级到手动选择;
    • 预授权检测:通过 abilityAccessCtrl.verifyAccessTokenSync 提前判断,避免连续弹窗导致应用被系统 kill。
  3. 数据持久化安全

    • 关键字段 AES-GCM 加密,密钥存于系统 Keystore,随用户锁屏自动失效;
    • 数据库打开默认 SQLITE_OPEN_PRIVATE,禁止外部应用直接访问 URI;
    • 备份关闭:allowBackup=false,防止 adb 导出明文。

生产环境避坑指南

  • 调试工具:DevEco Profiler 4.0 新增 ArkTS 内存采样,可定位 @Observed 对象泄漏;抓 Trace 用 hitrace 命令,比 Systrace 开销低 20%。
  • 真机部署:高校常见 Mate 60 系列需签名证书,用学校邮箱申请 OEM 证书,否则调试版 HAP 只能装 7 天。
  • API 兼容:Stage 模型从 4.0 开始移除部分 @system.router 接口,老教程里的 router.push 需改为 router.pushUrl,并在 module.json5 声明 router 版本。
  • 版本控制:.gitignore 必须加上 *.hap/entry/build,避免二进制冲突;CI 用官方镜像 openharmony/docker-ci:4.0,10 分钟可编完 32 位 + 64 位双包。

结语:让毕设成为上线的第一步

把架构做松、把状态做轻、把安全做硬,一份符合生产规范的 OpenHarmony 应用就完成了。毕设答辩不是终点,下一步不妨思考:如何补上账号体系、灰度更新、崩溃上报,让作品真正走进应用市场?当你能在简历里写下“已上架鸿蒙应用,累计用户 3k+”,那份毕业设计才真正拥有了长久的生命力。

领取优惠


Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐