Kotlin 睡眠质量评分与建议工具
本文介绍了一个基于Kotlin/JS与OpenHarmony ArkTS的跨端睡眠分析应用案例。该案例通过Kotlin实现核心业务逻辑sleepQualityAnalyzer函数,分析用户输入的睡眠数据(入睡/起床时间、夜醒次数、咖啡因摄入),给出质量评分和建议。Kotlin代码被编译为ES模块导出到JS,再由ArkTS页面调用。应用界面提供输入框和按钮,用户可实时查看分析结果。案例展示了如何用K
基于 Kotlin/JS + OpenHarmony ArkTS 的跨端睡眠分析小案例,通过一份 Kotlin 业务代码同时服务 JS 与鸿蒙端 UI。
1. 案例简介

本小案例的目标是:
- 从 Kotlin 侧实现一个
sleepQualityAnalyzer函数,接收一行简单的睡眠数据文本,例如23:30 07:00 2 1。 - 在 JS 中以 ES Module 形式导出,通过
hellokjs.js暴露给 ArkTS 调用。 - 在 ArkTS 页面中提供输入框与按钮,用户可以输入自己的一天睡眠情况,实时看到评分结果与文字建议。
与之前的「每日时间分配与效率分析」「环境体感舒适度指数」「随机抽奖」「任务优先级排序」等案例相比,这个案例更加聚焦在「个人健康与作息」这个维度,用非常轻量的规则模型给出一个可解释的睡眠质量评分。
2. Kotlin 侧实现:sleepQualityAnalyzer
Kotlin 代码位于 src/jsMain/kotlin/App.kt,通过 @JsExport 导出到 JS。函数输入为一行字符串:
- 入睡时间(24 小时制,格式
HH:mm) - 起床时间(24 小时制,格式
HH:mm,支持跨天) - 夜间醒来次数
- 当天咖啡因饮用杯数
示例输入:23:30 07:00 2 1 表示 23:30 入睡,第二天 7:00 起床,夜间醒来 2 次,当天喝了 1 杯咖啡或含咖啡因饮料。
下面是核心 Kotlin 实现(节选):
@OptIn(ExperimentalJsExport::class)
@JsExport
fun sleepQualityAnalyzer(inputText: String = "23:30 07:00 2 1"): String {
val parts = inputText.trim().split(" ").filter { it.isNotEmpty() }
if (parts.size < 4) {
return "❌ 错误: 请按 '入睡时间 起床时间 夜醒次数 咖啡因杯数' 的格式输入,例如: 23:30 07:00 2 1"
}
fun parseTime(text: String): Pair<Int, Int>? {
val segs = text.split(":")
if (segs.size != 2) return null
val h = segs[0].toIntOrNull() ?: return null
val m = segs[1].toIntOrNull() ?: return null
if (h !in 0..23 || m !in 0..59) return null
return h to m
}
val sleepTime = parseTime(parts[0])
val wakeTime = parseTime(parts[1])
val wakeCount = parts[2].toIntOrNull()
val caffeineCups = parts[3].toIntOrNull()
if (sleepTime == null || wakeTime == null || wakeCount == null || caffeineCups == null) {
return "❌ 错误: 时间或数字解析失败\n示例: 23:30 07:00 2 1"
}
val (sh, sm) = sleepTime
val (wh, wm) = wakeTime
val startMinutes = sh * 60 + sm
var endMinutes = wh * 60 + wm
if (endMinutes <= startMinutes) {
endMinutes += 24 * 60
}
val durationMinutes = endMinutes - startMinutes
val durationHours = durationMinutes / 60.0
val lengthScore = when {
durationHours in 7.0..9.0 -> 50
durationHours in 6.0..7.0 || durationHours in 9.0..10.0 -> 35
durationHours in 5.0..6.0 || durationHours >= 10.0 -> 20
else -> 10
}
val continuityScore = when {
wakeCount <= 1 -> 30
wakeCount == 2 -> 22
wakeCount == 3 -> 15
else -> 8
}
val habitScore = when {
caffeineCups == 0 -> 20
caffeineCups == 1 -> 15
caffeineCups in 2..3 -> 10
else -> 5
}
val totalScore = (lengthScore + continuityScore + habitScore).coerceIn(0, 100)
val qualityLevel = when {
totalScore >= 85 -> "🟢 优秀"
totalScore >= 70 -> "🟡 良好"
totalScore >= 55 -> "🟠 一般"
else -> "🔴 较差"
}
// 组装详细文字结果(省略部分字符串拼接)
// 返回值是多行中文说明,可直接在 ArkTS 界面 Text 中展示
return "…" // 实际项目中为完整的多段分析文本
}
这段 Kotlin 代码体现了几个关键点:
- 纯业务逻辑:不依赖 Android、iOS 或 ArkTS,仅使用标准 Kotlin API,适合作为 KMP 共享代码。
- 明确的输入约定:用一行字符串承载睡眠时间、夜醒次数和咖啡因摄入量,方便从 ArkTS 传递参数。
- 可解释的规则模型:把总分拆成“时长得分 + 连续性得分 + 习惯得分”,每一部分都有清晰含义,便于用户理解结果。
3. JS 导出:hellokjs.js 中的接口
Kotlin Multiplatform 编译后,会在 build/js/packages/hellokjs/kotlin/hellokjs.mjs 中生成 ES Module 代码,通过脚本复制并重命名为 pages/hellokjs.js。在 JS 侧,我们可以像普通 ES 模块那样导入并调用:
// hellokjs.js(示意用法,非完整编译产物)
import { sleepQualityAnalyzer } from './hellokjs.mjs';
const input = '23:30 07:00 2 1';
const resultText = sleepQualityAnalyzer(input);
console.log(resultText);
在实际工程中你无需手写这个包装代码,Kotlin/JS 编译器已经帮你导出 sleepQualityAnalyzer,只需要在 ArkTS 里从 ./hellokjs 导入即可,这一点与项目中其它案例(如 BMI 计算器、环境舒适度指数)保持一致。
4. ArkTS 页面:在 Index.ets 中调用 Kotlin 函数
OpenHarmony 端的 ArkTS 页面位于:
kmp_ceshiapp/entry/src/main/ets/pages/Index.ets
这里通过 ES 模块导入刚才生成的 sleepQualityAnalyzer,并将它绑定到按钮点击事件和页面初次加载逻辑中:
import { sleepQualityAnalyzer } from './hellokjs';
@Entry
@Component
struct Index {
@State message: string = '请输入睡眠时间和习惯信息';
@State inputText: string = '23:30 07:00 2 1';
@State resultText: string = '';
aboutToAppear(): void {
this.analyzeSleep();
}
analyzeSleep(): void {
try {
const input: string = this.inputText;
const result: string = sleepQualityAnalyzer(input);
this.resultText = result;
this.message = '✓ 分析完成';
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.message = `✗ 错误: ${errorMessage}`;
}
}
build() {
Column() {
// 头部标题栏 + 输入区 + 结果区(略)
}
}
}
在 UI 上,用户可以:
- 修改输入框中的文本,例如改成
00:10 06:00 4 4来模拟熬夜加高咖啡因的情况; - 点击“开始睡眠分析”按钮,实时重新计算睡眠得分和建议;
- 查看滚动区域中的详细文字结果,包括基础统计、评分构成、分项点评与综合建议等。
通过这种方式,Kotlin 中的纯逻辑函数被完整复用到 ArkTS UI 中,既保证了类型安全,又让业务逻辑集中在一处维护。
5. 生成与替换 hellokjs.d.ts / hellokjs.js 的流程说明
为了让 ArkTS 正确识别 sleepQualityAnalyzer 的类型信息,同时拿到最新的 JS 实现,本项目提供了自动编译与复制脚本:
- 执行构建脚本(Windows 下):
- 在项目根目录
kmp_openharmony下运行:build-and-copy.bat或build-and-copy.ps1。 - 脚本会调用
gradlew build,使用 Kotlin/JS IR 后端生成hellokjs.mjs与hellokjs.d.ts。
- 在项目根目录
- 复制与重命名:
- 从
build/js/packages/hellokjs/kotlin/复制hellokjs.d.ts与hellokjs.mjs。 - 将它们放入
entry/src/main/ets/pages/目录,并把.mjs重命名为hellokjs.js,以便 ArkTS 侧按模块名./hellokjs导入。
- 从
- ArkTS 使用
.d.ts提供的类型提示:hellokjs.d.ts自动包含了sleepQualityAnalyzer的签名,DevEco Studio/VS Code 可以基于它提供智能补全和类型检查。
整个链路依然遵循你在“编译成 JavaScript 并在 ArkTS 中调用”那篇文章里总结的通用模式,只是这里换成了一个睡眠分析的业务场景。
6. 案例设计思路与扩展方向
从教学和实践角度看,这个小案例有几个值得注意的设计点:
- 输入模型极简:只用一行字符串承载所有参数,既方便 UI 绑定,又让后续扩展(例如增加是否午睡、是否运动等字段)变得相对简单。
- 评分逻辑可读:把总分拆分为时长、连续性、习惯三部分,各自的分段规则全部硬编码在 Kotlin 中,便于初学者理解“规则引擎”这种模式。
- 结果为人类可读文本:返回值不是 JSON,而是多段带 Emoji 的中文说明,非常适合直接在 UI 文本区域展示;同时在 ArkTS 侧不必再做复杂的数据映射。
- 跨端复用价值明显:以后如果你希望在 Web/H5 或 Node.js 脚本中复用同一套睡眠打分规则,可以直接引入
hellokjs.mjs,做到一处维护,多处使用。
进一步可以演化的方向包括:
- 改用结构化数据模型:例如把输入改成 JSON 字符串,或者导出一个接收多参数的
@JsExport数据类,让类型信息更丰富。 - 引入历史数据分析:不仅分析单天睡眠,而是传入一周或一月的记录,计算趋势、波动和长期平均得分。
- 结合其他案例:例如把“学习打卡统计”“每日时间分配分析”和本案例组合起来,做一个完整的「生活习惯综合评估」页面,让 Kotlin 侧成为统一的分析引擎。
通过这样一个相对贴近日常生活的工具示例,可以很好地向读者展示:
- 如何在 KMP 中编写与平台无关的业务逻辑;
- 如何通过 Kotlin/JS IR 后端把逻辑导出到 JavaScript;
- 如何在 OpenHarmony ArkTS 中像调用普通 JS 模块一样使用这些逻辑;
- 以及如何围绕同一个核心函数,构建出跨端一致的用户体验。
7. 小结
本案例在原有工程体系之上,新增了一个「睡眠质量评分与建议工具」,完整走通了:
- 在 Kotlin 中定义
@JsExport函数sleepQualityAnalyzer; - 使用 Gradle 与脚本生成最新的
hellokjs.d.ts/hellokjs.js; - 在 ArkTS 的
Index.ets页面中导入并调用该函数; - 在 UI 中实时展示面向用户的分析结果文本。
如果你已经熟悉了项目中其它工具型与小游戏型案例,这个睡眠分析小案例可以作为一个健康生活场景的补充示例,也可以作为进一步构建「个人习惯数据分析面板」的基础模块之一。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)