Kotlin 睡眠质量评分与建议工具
摘要: 本案例展示了一个基于Kotlin/JS与OpenHarmony ArkTS的跨端睡眠质量分析工具。通过Kotlin实现核心业务逻辑sleepQualityAnalyzer函数,该函数接收"入睡时间 起床时间 夜醒次数 咖啡因杯数"格式的输入(如"23:30 07:00 2 1"),计算睡眠时长、连续性等指标,输出0-100分的评分及健康建议。Kotl

基于 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 "…" // 实际项目中为完整的多段分析文本
}
这是睡眠质量评分与建议工具的核心实现函数。函数使用 @OptIn(ExperimentalJsExport::class) 和 @JsExport 注解,使其可以被编译成 JavaScript 并在 ArkTS 中调用。函数首先进行输入解析,使用 split(" ") 将输入字符串分割为四部分(入睡时间、起床时间、夜醒次数、咖啡因杯数),使用 filter { it.isNotEmpty() } 过滤空字符串。然后验证输入格式,检查是否包含四个部分。定义一个内部函数 parseTime() 用于安全解析时间字符串,将 “HH:mm” 格式转换为小时和分钟的 Pair。使用 toIntOrNull() 安全转换数字,避免非法输入导致崩溃。计算睡眠时长,将时间转换为分钟数,处理跨天的情况(如果起床时间小于入睡时间,则加 24 小时)。使用 when 表达式根据不同的睡眠时长、夜醒次数和咖啡因摄入量计算三部分得分:时长得分、连续性得分和习惯得分。计算总分,使用 coerceIn(0, 100) 确保分数在 0-100 范围内。根据总分判断睡眠质量等级,分为四个等级:优秀、良好、一般、较差。最后返回格式化的多行中文说明文本,包含睡眠数据、评分构成和建议。
这段 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);
这段代码展示了如何在 JavaScript 环境中调用编译后的 Kotlin 函数。首先使用 import 语句从编译后的 JavaScript 模块 hellokjs.mjs 中导入 sleepQualityAnalyzer 函数。然后定义输入字符串 '23:30 07:00 2 1',表示 23:30 入睡,第二天 7:00 起床,夜间醒来 2 次,当天喝了 1 杯咖啡因饮料。调用 sleepQualityAnalyzer(input) 函数,传入输入字符串,获取睡眠质量分析结果。最后使用 console.log() 输出结果。这展示了 KMP 的跨端能力,同一份 Kotlin 代码可以在 JavaScript 环境中无缝调用。
在实际工程中你无需手写这个包装代码,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() {
// 头部标题栏 + 输入区 + 结果区(略)
}
}
}
这段 ArkTS 代码是鸿蒙应用的用户界面实现,通过 import 语句导入之前编译的 Kotlin 函数。使用 @State 装饰器定义三个响应式状态变量:message 用于显示状态信息,inputText 存储用户输入的睡眠数据(默认为 “23:30 07:00 2 1”),resultText 存储分析结果。aboutToAppear() 生命周期函数在组件加载时自动调用 analyzeSleep() 进行初始分析。analyzeSleep() 方法调用 Kotlin 编译的 JavaScript 函数 sleepQualityAnalyzer(),将用户输入的文本传入,获取睡眠质量分析结果,然后更新 resultText 和 message。使用 try-catch 块捕获异常,如果发生错误则显示错误信息。build() 方法构建整个 UI 布局,包含标题栏、输入区和结果显示区。这个结构实现了清晰的前后端职责划分:ArkTS 只负责收集输入和展示结果,所有睡眠质量评分逻辑都集中在 Kotlin 中。
在 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 中实时展示面向用户的分析结果文本。
如果你已经熟悉了项目中其它工具型与小游戏型案例,这个睡眠分析小案例可以作为一个健康生活场景的补充示例,也可以作为进一步构建「个人习惯数据分析面板」的基础模块之一。
更多推荐



所有评论(0)