淦!——我的Harmony OS for PC首秀——必须做开源

前言
前几天做了一款鸿蒙的PC应用,一次上架成功,我对比了一下应用市场,我还是第一款呢,如果以后大家都用的话那流量肯定呼呼的,我第一个版本做了个单机的,后面有机会吧所有的排行榜弄成在线排名,搞个redis的全国排行榜,肯定超级秀。
鸿蒙PC应用【师傅打字】市场:https://appgallery.huawei.com/app/detail?id=com.faquan.faquan_test&channelId=SHARE&source=appshare
师傅打字 设计初衷: 在这个数字化时代,键盘已成为我们思维的延伸。无论是深夜敲击的代码,还是忙碌时回复的邮件,打字的速度与准度往往决定了灵感的流淌是否顺畅。“师傅打字”诞生的目的很简单:让枯燥的指法练习变成一场指尖上的审美旅程,让每一次敲击都充满意义。
注:做之前我就在鸿蒙PC上搜了,没有搜索到相关的鸿蒙PC端的打字应用,所以我的第一款。
目录
开源说明
这是鸿蒙PC的正式上架的打字应用,相对来说的前瞻性还是有的,做成开源也是为了让更多的创意,点子放进来,有想法我来逐步的完善这款应用,希望可以帮助到更多的刚入门的技术人员们,毕竟现在技术人员绝对不止一个亿了,用电脑的人们会更加的多,我也不想着给我自己创造什么价值,最好的就是让所有人都有进步,毕竟,我们祖国的目标是人人如龙。
开源地址:https://gitcode.com/feng8403000/shifudazi
一、环境说明与基础技术点说明
开发环境:DevEco Studio 6.0.1
SDK版本:HarmonyOS Next (API 21)
编程语言:ArkTS (TypeScript)
UI框架:ArkUI
存储:关系型数据库 (RelationalStore)
多线程:Worker (用于处理复杂的后台统计计算)

RelationalStore说明
大家对【RelationalStore】可能不熟悉:
RelationalStore 是鸿蒙(HarmonyOS)系统原生提供的关系型数据库模块,隶属于 ArkData(方舟数据管理),基于 SQLite 引擎构建,为应用提供结构化数据的持久化、事务、加密、分布式同步等能力。
HarmonyOS 系统级数据持久化方案之一,包路径为【@ohos.data.relationalStore】,是关系型数据管理的标准 API。
底层依赖:基于 SQLite,兼容 SQL 语法,同时针对鸿蒙设备做了轻量优化与安全增强。
使用环境:面向结构化数据(如订单、聊天记录、用户信息),支持表结构、JOIN 查询、事务、索引、加密、分布式同步与向量检索等。
其它数据库解决方案对比:
| 方案 | 数据模型 | 适用场景 | 核心优势 |
|---|---|---|---|
| RelationalStore | 关系型表 | 复杂结构化数据、事务、跨设备同步 | 完整 SQL 能力、事务保障、分布式支持 |
| Preferences | 键值对 | 简单配置(如主题、音量) | 轻量、内存缓存、快速读写 |
| KV-Store | 键值对 | 非结构化 / 半结构化数据 | 分布式能力强、跨设备同步简单。 |
RelationalStore 基础使用示例:
这是一套基础的使用代码,可以参考使用,在线仓库里有具体的使用示例。
import relationalStore from '@ohos.data.relationalStore';
// 1. 配置与获取数据库实例
const storeConfig = {
name: 'user_db.db',
securityLevel: relationalStore.SecurityLevel.S1
};
let rdbStore: relationalStore.RdbStore | null = null;
relationalStore.getRdbStore(storeConfig, (err, store) => {
if (err) {
console.error(`获取数据库失败: ${err.message}`);
return;
}
rdbStore = store;
// 2. 建表(用户表)
const createTableSql = `
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER
)
`;
rdbStore.executeSql(createTableSql, (err) => {
if (err) {
console.error(`建表失败: ${err.message}`);
return;
}
// 3. 插入数据
const values = { name: '张三', age: 25 };
rdbStore.insert('users', values, (err, rowId) => {
if (err) {
console.error(`插入失败: ${err.message}`);
return;
}
console.log(`插入成功,行ID: ${rowId}`);
});
});
});
注:
单条数据建议不超过 2MB,避免性能下降。
数据库操作建议异步执行,避免阻塞主线程。
多线程:Worker 说明
在鸿蒙(HarmonyOS)应用开发中,Worker 是用于实现多线程并发处理的核心机制,其设计目标是将耗时任务(如数据计算、文件解析、网络请求)从主线程(UI 线程)剥离,避免主线程阻塞导致的界面卡顿。
| 概念 | 说明 |
|---|---|
| 主线程 | 负责 UI 渲染、事件响应,禁止执行耗时操作(单次阻塞超过 50ms 会触发卡顿检测)。 |
| Worker 线程 | 独立于主线程的后台线程,可执行耗时任务,不能直接操作 UI 组件。 |
| 通信机制 | 主线程与 Worker 线程通过 消息传递 交互(序列化数据),支持双向通信。 |
| 线程隔离 | Worker 线程有独立的上下文,无法访问主线程的变量、对象和 UI API。 |
本项目采用的是内置 Worker,相对优势下标可见,毕竟我没有写跨模块与跨应用,所以单应用内容使用 内置 Worker 是最为合适的了。
| 特性 | 内置 Worker(本项目) | 外置 Worker |
|---|---|---|
| 文件位置 | 项目内部 entry/ets/workers/ |
单独的 HAR 包或共享库 |
| 引用方式 | entry/ets/workers/TypingWorker.ts |
'@bundle:bundleName/moduleName/ets/workers/xxx' |
| 打包方式 | 随主应用打包 | 独立打包,可复用 |
| 适用场景 | 单应用内部使用 | 多模块/跨应用共享 |
内置 Worker,ArkTS 示例:
完整开发流程分为 主线程创建 Worker、Worker 线程处理任务、双向通信、销毁 Worker 四步。
主线程侧代码:
import worker from '@ohos.worker';
// 1. 创建Worker实例(指定Worker脚本路径)
const workerInstance = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts');
// 2. 接收Worker线程的消息
workerInstance.onmessage = (e) => {
console.log(`主线程接收结果: ${JSON.stringify(e.data)}`);
// 处理结果(如更新UI)
// 注意:主线程可操作UI,Worker线程不可
};
// 3. 监听Worker错误
workerInstance.onerror = (err) => {
console.error(`Worker错误: ${err.message}`);
};
// 4. 向Worker线程发送任务数据
const taskData = {
type: 'calculate',
data: [1, 2, 3, 4, 5]
};
workerInstance.postMessage(taskData);
// 5. 任务完成后销毁Worker(避免内存泄漏)
const destroyWorker = () => {
workerInstance.terminate();
};
Worker 线程侧代码:
// Worker线程的全局对象是 workerPort,而非 window
import worker, { ThreadWorkerGlobalScope, MessageEvents } from '@ohos.worker';
// 获取Worker全局作用域
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
// 监听主线程发送的消息
workerPort.onmessage = (e: MessageEvents) => {
const { type, data } = e.data;
if (type === 'calculate') {
// 执行耗时任务:计算数组元素的累加和
const sum = data.reduce((a: number, b: number) => a + b, 0);
// 向主线程返回结果
workerPort.postMessage({ result: sum });
}
};
// 监听错误
workerPort.onerror = (err) => {
console.error(`Worker内部错误: ${err.message}`);
};
API 与通信规则
| 主线程 API | 作用 |
|---|---|
new ThreadWorker(scriptPath) |
创建 Worker 实例 |
postMessage(data) |
向 Worker 发送数据(支持 JSON、ArrayBuffer 等可序列化类型) |
onmessage |
接收 Worker 的消息回调 |
terminate() |
主动销毁 Worker,释放资源 |
| Worker 线程 API | 作用 |
|---|---|
workerPort.postMessage(data) |
向主线程发送结果 |
workerPort.onmessage |
接收主线程的任务指令 |
workerPort.close() |
Worker 内部主动关闭线程 |
注:
- 支持可序列化数据:基本类型(number/string/boolean)、JSON 对象、ArrayBuffer、TypedArray。
- 不支持:函数、DOM 对象、循环引用对象、鸿蒙 UI 组件对象。
- 单个应用最多创建 8 个 Worker 线程,超出会抛出异常。
- 避免创建过多 Worker,建议通过任务队列复用线程。
音频创造
我单独的写了一篇文章来表述这里:https://blog.csdn.net/feng8403000/article/details/156688388
这是音波范围:
| 按键类型 | 频率范围 | 步进值 | 音效特征 |
|---|---|---|---|
| 字母 a-z | 800Hz - 1100Hz | 12Hz | 清脆中音,接近青轴 |
| 数字 0-9 | 600Hz - 750Hz | 15Hz | 低沉稳重 |
| 符号键 | 450Hz | - | 低频厚重感 |
生成的方式在我的代码里面能看到,我单独用python创建的音频文件。
二、核心功能与解决未来鸿蒙世界的大学生核心问题
其实我准备了好多的功能,不过开发的速度没那么快,一点点的进步与成长,同时也希望大家能多提提意见,我根据大家的意见与想法来慢慢的补全各类功能,但是当前的功能绝对是够用的呢。

核心功能
核心能力:支持英文录入训练、中文拼音录入训练、打字速度基准测试 三大核心场景。
实时指标统计:运行时实时计算并输出 WPM(每分钟输入字数)、字符准确率、有效练习时长等核心量化指标,数据采样粒度为单次按键事件。
指法引导引擎:内置标准盲打指法映射规则,实时检测用户击键手指匹配度,输出动态矫正提示,支持从非标准指法(二指禅)到专业盲打的阶梯式进阶训练。
解决未来鸿蒙世界的大学生核心问题
每次带大一新生的时候都会进行一些小比赛,就类似于打字比赛,毕竟如果打字跟不上,上课真的很难受。

速度有快有慢。

这速度也不慢。

大一的孩子每年都有,想解决二指禅/一阳指的问题如果有好用的应用就会快很多。
三、升级变化
我对原来我们经常用的打字练习工具做了一定的升级,可以在面板上看到,每次输入的内容我都进行了记录,并且最后会放在数据记录板上面,能一直对自己的练习进度有个提示说明。

数据记录板1、巅峰荣誉看板
这里会详细的记录你个人的每次比赛信息,很有成就感哦。

数据记录板2、输入记录
输入了多少次字母,文字输入多少次,符号输入多少次,都被我记录了,你经常打的内容都有记录,还有总练习时长,累计正确率(算平均值)。
为了数据好看,你也会好好打字的,是吧?

指法提示
这里我单独的绘制了一个打字效果的图片,是GIF的,可以看到对应的指法。

总结
内容上我觉得我还是做了很多优化的,希望能创造更多的价值,我总是觉得鸿蒙就是我们未来几十年的方向,所以我会一直在这个方向上创造我的价值。
更多推荐




所有评论(0)