HandyReader Blog

2026上半年,Handy Reader 开发得咋样了?

翻了翻日志,过完年到现在,260 多次提交,13 个版本,基本上每 1-2 周发一版。 一晃 2026 已经过半,也该停下来盘点下这半年都干了些什么。

几个大的功能节点

三月 · 引擎重构

之前的翻页逻辑散落在好几个类里,耦合越来越重,修一个 bug 常常牵一发动全身。我花了大概两周,用 Facade 模式把排版、渲染、翻页动画的组件重新梳理了一遍,再配合 LRU 缓存的版本号机制,才彻底解决了缓存不一致的老问题。 同期还修复了颜色选择器,加了点击区域模式和左手模式——算是对阅读交互的第一轮大修。 月底上线了阅读背景图选择。用户可以选系统纹理,也可以从相册挑自己的图。功能看起来不大,但背后把 DataStore 主题配置拆成了独立的 theme_prefs,折腾了好一阵。

四月 · TTS 升级

之前用的是 Android 系统 TTS,效果嘛……只能说能用。这次换上了 Sherpa ONNX 离线 AI 引擎,支持中英日等多语言,配合语速/音高调节和定时器,效果比系统 TTS 高了一个档次。和竞品比也算是一个差异点,后续值得继续深挖。 同月还做了用户反馈系统——后端用 Go 写了反馈 API,集成了邮件通知,用户可以直接在应用内提交反馈,我能第一时间收到。

五月 · 字体、词典、翻译、多语言

字体系统——支持从 CDN 下载 30+ 款中英文字体,也支持从本地导入。变体自动识别(Regular/Bold/Italic 等),阅读器内自由切换。 词典 + 翻译——阅读页查词上线,集成了 Free Dictionary API、Wiktionary、中文字典等多个数据源。选中文字可以直接翻译。为此还专门搭了一个 Cloudflare Workers 词典服务,部署在 dict.handyreader.top,覆盖 10+ 语言。 同期还做了繁体中文支持。

六月 · 垂直滚动 + 首页改版

连续垂直滚动——这个功能从三月初就开始动手,断断续续搞了三个月才稳定下来。垂直滚动模式下,高亮、下划线、笔记、文字选择、跳转、TTS 跟随、文字搜索……所有分页模式下的功能,全都得在连续垂直滚动里重新适配一遍。踩了一堆坑:缓存失效、绘制错位、章节加载时序问题。好在六月中总算交了卷。 首页全面改版——之前就是书架网格,新版加了首页、最近阅读、阅读热力图。不再只是个书架,更像一个阅读仪表盘了。 同月还有:

  • 从其他应用直接打开书籍文件
  • 书籍内搜索
  • 全局 UI 统一(Slider 替换、封面图规范、色彩对齐)
  • 阅读页样式主题
  • OPDS 在线书库

七月 · 同步与 PDF

七月做了备份与还原——支持封面图同步、跨设备还原进度、基于 SHA-256 的图书去重、孤儿书(orphan)提升机制。以及书籍独立主题配置,不同书可以有不同的主题色和排版设置,不再是全局一套打天下。 七月剩下的时间,重点就是 PDF 的解析排版和渲染了。这个很重要,必须啃下来。

配套的 Web 生态

除了 App,这半年还搭了一套配套的 Web 服务:

  • handyreader.top (https://handyreader.top) — 多语言官网,15 种语言,集成了博客、FAQ、反馈、隐私政策。静态 HTML,Python + data-i18n 生成多语言。
  • Go 后端 API — 反馈处理、翻译配额、Sherpa 模型数据、阅读背景图
  • 词典 API — Cloudflare Workers 上的 10+ 语言词典查询
  • ASO 看板 — Next.js 关键词排名监控,每天自动爬 Google Play 排名,配合 DeepSeek 生成 AI 日报
  • AppShotDeck — 浏览器端商店截图制作工具,做 Google Play 展示图用的(这个工具也挺有意思,后面单独聊)
  • OPDS 书源目录 — 整理了多个中文可用的 OPDS 源

踩坑与反思

几个印象深刻的技术决策:

  1. 主题配置独立 DataStore — 早期主题和通用设置混在一起,缓存互相干扰。拆成独立的 theme_prefs DataStore 后,问题彻底解决。
  2. contentHash 去重 — 旧的去重靠文件名 + CRC,不同设备间不稳定。后来改用 SHA-256 做主匹配,导入和还原两侧的匹配键统一了。
  3. SAF 的 skip 陷阱 — InputStream.skip() 不保证跳过指定字节数,SAF 路径下尤其不可靠。因为没有走大多数电子书那种全盘文件权限的路线,在文件访问上绕了不少弯路。

收获

对电子书来说,解析、排版、渲染是三大核心。自研这三套系统确实不容易,但好处是底层的原理和脉络我很清楚,出了问题知道该去哪翻。坏处是起步慢,得先把系统捋顺了,否则后面处处是坑。回头看,这个选择是对的——虽然前期慢,但积累的东西都是自己的。

下一步

WebDAV 同步还在路上,代码写了一半。更好的 PDF 渲染和显示是眼下的硬仗。再远一点,考虑往 Kotlin Multiplatform 迁,做跨平台支持。 时间过得很快,还是要好好珍惜时间,下半年继续,争取把这些坑都填上。 非常感谢所有用户的支持和反馈——你们提的每一个 issue,都是我深夜改 bug 的动力!😄