← 返回全部文章

文章 ·

从读一本书开始:taobook 的开发历程

从 iOS 阅读器到 Android 与鸿蒙原生版,记录 taobook 如何处理多格式阅读、翻译与朗读。

电子书格式很多,阅读却常常被格式、设备和应用功能打断:一份资料是 EPUB,另一份是 PDF;想听书时,朗读位置又和眼前的文字脱节。我做 taobook,就是希望把导入、阅读、查找、翻译和朗读放进一条顺畅的使用路径里。

taobook(淘书阅读器)是一款面向个人的阅读应用。它以本地图书为起点:用户选择自己的文件,应用建立书库、保存阅读位置,再根据内容提供目录、搜索、书签、批注或朗读。需要在线能力时,可以添加书源,或自行配置模型服务进行翻译和对话。阅读本身不要求先有账号或模型密钥。

系统架构一览

三个客户端分别实现导入、阅读和本地保存。iOS 与 Android 还提供在线书源和可选的模型能力;鸿蒙原生版目前聚焦本地阅读与系统朗读。三端之间尚无数据同步。

taobook 系统架构:iOS、Android 与鸿蒙原生客户端分别处理本地阅读,前两者可按需连接在线服务

点击架构图可以查看大图。

第一站:在 iPhone 上把阅读体验做完整

项目最早围绕 iOS 展开,阅读内核基于 Readium Swift Toolkit。我先处理了电子书应用最基础、也最容易被低估的部分:不同格式的导入、EPUB 与 PDF 的呈现、书库管理、阅读进度和阅读设置。TXT 与 Markdown 可以转换为适合阅读器处理的内容;书源则通过 OPDS 扩展了寻找和打开内容的入口。

后来,taobook 逐渐从“打开一本书”走向“理解和使用一本书”。阅读时可以调用系统或用户配置的模型服务翻译内容,朗读则提供系统声音和模型语音的选择。翻译结果也能保存下来继续阅读。这里有一个贯穿开发的原则:模型能力应该服务于阅读,而不应该成为阅读的前提。

真正花时间的往往是细节。例如,朗读工具栏需要由读者点击显示、再次点击隐藏,播放状态变化不能抢走这个控制权。再例如,MOBI 和 AZW3 不能直接交给 EPUB 阅读内核;对于未加密文件,需要先在本机转换,并保证生成的 EPUB 章节和 XHTML 能被稳定解析。一次真机排查就发现,转换“成功”不等于整本书真的能读,必须翻到后面的章节继续验证。

第二站:为 Android 重新实现,而不是照搬界面

做 Android 版时,目标是保留 taobook 的产品结构,同时使用适合 Android 的技术栈。应用采用 Kotlin、Jetpack Compose 和 Readium Kotlin Toolkit;图书与聊天记录保存在本地数据库中,阅读偏好单独持久化。导入通过系统文件选择器完成,让用户明确选择文件,也避免为了读书申请全盘存储权限。

Android 版逐步补齐了书库、EPUB/PDF 阅读、书签与高亮、阅读助手、书源管理、RSS/Atom 文章阅读、模型设置和文本聊天。文章阅读不只是打开网页:它还要面对正文抽取、目录、搜索、进度、朗读中断和网络失败。聊天也不只是显示一段回答,还要处理流式输出、停止生成、历史记录与重试。

这段开发让我更清楚地看到,跨平台的一致性不等于每一端使用相同代码。读者需要的是相近的操作路径和可靠的结果;文件系统、阅读内核、语音服务和界面生命周期,则必须按各自平台的方式实现。

第三站:为鸿蒙做一套原生阅读器

鸿蒙原生版并非 Android APK 的换壳。它使用 ArkTS、ArkUI 和 ArkWeb 组织书库与 EPUB 阅读,接入系统离线语音完成分段朗读、跨章继续和正文高亮。EPUB、PDF、TXT、Markdown,以及未加密的 MOBI/AZW3,都有各自的导入和显示处理。

这一版刻意先收紧范围:把本地图书导入、阅读进度和听书体验做好,再考虑与其他平台的功能对齐。开发中遇到的空白章节、目录标题不准、停止朗读后意外跳到下一段等问题,也都需要回到真机上观察和修正。它提醒我:构建通过只是起点,真正的阅读体验发生在具体的书和具体的设备上。

接下来

现在的 taobook 已经有 iOS、Android 和鸿蒙三个方向,但它们仍是各自独立的应用,功能并不完全相同,也没有跨设备同步。加密图书、扫描版 PDF 的文字识别等场景,还有明确的边界。

我会继续沿着最初的目标打磨它:让自己的书更容易导入、读得更顺、听得更自然;在确实有帮助的地方加入翻译和对话,同时把文件处理、阅读进度和隐私选择做好。对一款阅读应用来说,最好的新功能,是让人更愿意回到书里。

评论

使用 GitHub 账号参与讨论。 前往 GitHub 评论

感谢阅读。 继续浏览文章 →