openGym训练时屏幕常亮原理:Wakelock锁屏机制完整解析
openGym训练时屏幕常亮原理Wakelock锁屏机制完整解析【免费下载链接】openGymSelf-hosted gym body-weight tracker — plan routines, log workouts (supersets, warm-ups, cardio), see which muscles are trained, fatigued or detrained, import from FitNotes/Strong/Hevy, passkey login. Your data, your server.项目地址: https://gitcode.com/GitHub_Trending/op/openGymopenGym 是一款自托管self-hosted的健身训练记录应用其中的Wakelock 锁屏机制能在训练全程让手机屏幕常亮——组间休息、翻动作库、看统计都无需反复解锁。本文完整解析它是如何基于浏览器 Screen Wake Lock API 实现的为什么“一次性请求”会悄悄失效、openGym 如何自动重新上锁、以及在哪些环境下该功能会不可用。一、为什么训练时屏幕常亮很重要想象一下两组卧推之间你低头看手机确认下一组的重量屏幕却因为锁屏超时熄灭了——解锁、点回来、再找位置打断的正是训练的连贯节奏。openGym 的引导式训练界面Guided Workout会自动开始当日训练、预填上次重量、组间运行休息计时器。如果此时屏幕黑了整套体验都会被打断。因此 openGym 内置了“Keep screen awake保持屏幕常亮”开关在训练会话期间通过 Wake Lock 锁屏机制阻止屏幕自动熄灭。二、功能入口在哪里打开屏幕常亮开启路径很简单设置 → 训练中During a workout→ Keep screen awake对应的界面实现位于 Settings.jsx开关状态保存在应用设置项keepAwake中默认为开启见 useStore.js。有两点值得注意浏览器不支持时开关会禁用界面通过wakeLockSupported()检测浏览器是否提供 Wake Lock API不支持时显示 “Not supported in this browser.”锁定与“训练会话”绑定而不是与“训练页面”绑定App.jsx 中的注释写得很清楚——训练中切到 Stats 页面看一眼数据屏幕依然保持常亮直到训练真正结束。三、核心机制57 行代码搞定“永不黑屏”整个 Wakelock 锁屏机制的核心实现集中在一个不到 60 行的模块wakelock.js。它依赖的是 Web 标准的Screen Wake Lock APInavigator.wakeLock.request(screen)。3.1 陷阱一次性请求为什么“悄悄失效”文件开头的注释点出了关键问题浏览器会在文档不可见时切换标签页、应用退到后台、手动锁屏主动丢弃锁。一次性请求只生效一次然后就悄无声息地失效了。也就是说如果代码只是简单地request()一次用户切个 Tab 再回来锁就已经没了——而且不会有任何报错提示。3.2 openGym 的解法状态 监听 自动重连模块用三个模块级变量维护“上锁意图”变量含义wanted我们当前是否想要屏幕常亮自己的意图标志sentinel当前持有的WakeLockSentinel没持有锁时为nullpending是否有一个request()正在飞行中防止重复叠加请求配合 acquire() 函数 的防御逻辑形成完整的锁屏机制前置检查不想要锁、已持有锁、已有请求在飞行中、浏览器不支持、文档不可见——任一条件成立直接返回文档不可见时request()会直接被浏览器拒绝。请求落地的竞态处理await期间如果用户已经调用了releaseWakeLock()返回的锁会被立即释放绝不泄漏。静默容错catch分支里注释写道——“iOS 在低电量模式下会拒绝一些浏览器在低电量时也会拒绝。没什么可做的安静失败等文档下次变为可见时再试。”自动重连注册visibilitychange监听器onVisible只要文档重新变为可见且仍处于训练会话中就重新acquire()。3.3 React Hook训练开始上锁结束放锁模块最后导出一个 useWakeLock(enabled) Hookenabled为真时请求锁组件卸载或条件变假时释放。在 App.jsx 中的接线方式是useWakeLock(!!S.active !S.active.editingWorkoutId S.keepAwake ! false)翻译成人话有进行中的训练 不在编辑界面 用户没有手动关闭开关三者同时满足就保持锁屏常亮。四、测试如何保证“切个Tab锁就丢”的坑被填上配套的测试文件 wakelock.test.js 的思路很值得学习既然整个模块的意义就是“扛住浏览器的自动丢锁行为”那么假浏览器也必须真的会丢锁——否则测试会放过一个“切一次标签页就死掉”的一次性实现。测试覆盖了几个关键场景✅ 训练开始能拿到锁且不会叠加第二把锁✅ 文档不可见时不会发起请求✅ 退到后台被浏览器丢锁后回前台自动重新获取requests从 1 变成 2✅ 被系统拒绝模拟 iOS 低电量模式后保持静默回前台自动重试✅ 请求“飞行中”时释放锁不会泄漏一把没人持有的锁✅releaseWakeLock()之后停止自动重连五、环境限制哪些情况下开关会“置灰”官方文档对这两个坑有明确说明部署时建议提前了解5.1 传输协议要求HTTPS 或 localhostdocs/SELF_HOSTING.md 指出Wake Lock API 只在HTTPS 或http://localhost下可用。如果你的自建实例通过纯局域网 IP如http://192.168.x.x访问开关会显示为不受支持。服务端无需任何额外配置。 这正是文章配图里架构层强调端到端 TLS 的原因之一——对普通用户而言配好 HTTPS 是解锁该功能的正确姿势。5.2 移动端的前台服务兜底在原生壳Capacitor 打包的 Android/iOS 应用里Android 侧另有兜底前台服务会在休息倒计时期间持有系统 wake lock保证屏幕锁定的情况下休息结束的铃声也能准时响起详见 docs/MOBILE.md。而 iOS 在低电量模式下会拒绝屏幕锁请求属于系统行为openGym 会静默降级。六、总结openGym 的屏幕常亮功能麻雀虽小五脏俱全一个意图标志wanted把“用户想不想常亮”和“锁还在不在”彻底解耦visibilitychange 自动重连专治浏览器“悄悄丢锁”️pending/sentinel 竞态防护释放时机落在请求飞行中也不会泄漏锁静默容错 延迟重试低电量拒绝不弹错、不打扰训练测试模拟器真实复现浏览器丢锁行为保证防线不退化如果你也在做健身类或计时类应用这套 57 行的 Wake Lock 锁屏机制wakelock.js几乎是教科书级的参考实现状态简单、失效路径全被覆盖、测试先行。需要体验完整功能的话可以克隆仓库后按 docker-compose.yml 启动服务git clone https://gitcode.com/GitHub_Trending/op/openGym训练时屏幕常亮从此告别组间解锁的打断。️【免费下载链接】openGymSelf-hosted gym body-weight tracker — plan routines, log workouts (supersets, warm-ups, cardio), see which muscles are trained, fatigued or detrained, import from FitNotes/Strong/Hevy, passkey login. Your data, your server.项目地址: https://gitcode.com/GitHub_Trending/op/openGym创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Gopeed 下载管理器实战:从装好到满速

Gopeed 下载管理器实战:从装好到满速

Gopeed 下载管理器实战:从装好到满速 【免费下载链接】gopeed A fast, modern download manager for HTTP, BitTorrent, Magnet, and ed2k. Cross-platform, built with Golang and Flutter. 项目地址: https://gitcode.com/GitHub_Trending/go/gopeed Gope…

2026/10/9 12:59:26 阅读更多 →
HyperFrames 新手实战:用 hyperframes add 一键装上现成视频组件

HyperFrames 新手实战:用 hyperframes add 一键装上现成视频组件

HyperFrames 新手实战:用 hyperframes add 一键装上现成视频组件 【免费下载链接】hyperframes Write HTML. Render video. Built for agents. 项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes 给口播视频配字幕,你不想从零搭动画…

2026/10/10 9:19:54 阅读更多 →
douyin-downloader:抖音无水印视频批量下载完整指南

douyin-downloader:抖音无水印视频批量下载完整指南

douyin-downloader:抖音无水印视频批量下载完整指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…

2026/10/9 12:59:38 阅读更多 →

最新新闻

STM32看门狗实战:IWDG与WWDG原理、配置及防死机方案

STM32看门狗实战:IWDG与WWDG原理、配置及防死机方案

干嵌入式最怕的一种状态,就是板子在现场跑着跑着突然死了,不是一两次,而是偶发性的,代码看了好几遍却找不到规律。我刚开始做项目那会儿,第一反应是怀疑电源、怀疑晶振、怀疑通讯被干扰,后来才发现这些问题…

2026/10/20 16:17:43 阅读更多 →
三菱PLC产线实战:FX5U与Q系列的运动控制与数据管理

三菱PLC产线实战:FX5U与Q系列的运动控制与数据管理

做自动化产线这些年,手头接触最多的就是三菱的PLC。FX5U和Q系列,一个走小型集成,一个走中大型分布式,搭配伺服、变频器、触摸屏,就能撑起一整条全自动化生产线的运动控制和数据管理。今天这篇,围绕我实际做…

2026/10/20 16:17:43 阅读更多 →
高压输入低压大电流场景下ISOP-DAB变换器的均压控制与PLECS仿真

高压输入低压大电流场景下ISOP-DAB变换器的均压控制与PLECS仿真

高压直流输入、低压大电流输出,是很多电源场景里绕不开的硬骨头。储能母线、充电桩功率模块、特种电源,经常要把几百伏甚至上千伏的直流电压,转换成几十伏、上百安培的输出。直接选一颗耐压够高的功率管确实能解决问题,但代价很直…

2026/10/20 16:17:43 阅读更多 →
RAG知识库检索实战:切块、双路召回与重排全解析

RAG知识库检索实战:切块、双路召回与重排全解析

“你做RAG项目的时候,知识库检索的召回率是多少?怎么调的?”——这是我准备智能RAG问答系统KnowLink的过程中,被问得最多、也最回答不漂亮的一个问题。最初我的项目能跑通Demo,答案也算流畅,但一旦被追问“…

2026/10/20 16:17:43 阅读更多 →
单片机位数怎么选?4位、8位、16位、32位差异详解

单片机位数怎么选?4位、8位、16位、32位差异详解

做单片机开发这些年,被新手朋友问得最多的一个问题,不是“怎么学C语言”,也不是“买哪块开发板”,而是——“4位、8位、16位、32位单片机,到底差在哪”。这个问题看着基础,真要掰开揉碎讲,能牵扯…

2026/10/20 16:17:43 阅读更多 →
SpringBoot + SSL证书实战:HTTP转HTTPS与WebSocket升级WSS全指南

SpringBoot + SSL证书实战:HTTP转HTTPS与WebSocket升级WSS全指南

最近在做某消息推送服务时,被前端同事催着把 WebSocket 从 ws 换成 wss,同时整个服务还得从 HTTP 升级到 HTTPS。折腾了两天,踩完证书格式、端口跳转、浏览器拦截这几个坑之后,我把整个流程完整走了一遍。这篇文章就是给同样要做 …

2026/10/20 16:16:42 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →