为什么要造这个轮子

我用 Memos 几年了。

对于熟悉自托管生态的人来说,Memos 不需要过多介绍——一个开源的、可自部署的轻量备忘录服务,数据完全掌握在自己手里,没有账号体系绑定,没有云端锁定,Docker 一行命令就能跑起来。它解决的问题很简单:快速记下脑子里的东西。服务端功能够用,但是有个问题,更新很快,且不向前兼容,安卓的三方客户端经常会用不了,需要等待升级。

随着 AI 能力的升级,我借助 claude code,写了一个新的安卓客户端,项目叫 Memosly,已经开源在 GitHub 上,目前也已经上架 Google Play 内测。


核心功能一览

完整的备忘录管理

作为 Memos 客户端,基础功能必须稳:

  • 新建、编辑、归档、删除
  • 可见性设置(公开 / 保护 / 私密)
  • #标签 语法 + 快速筛选
  • 全文搜索

这些在 Web 端能做的事,Memosly 里都能做,而且因为是原生 App,操作体感明显更流畅。

备忘录首页

Markdown 编辑器

编辑器支持完整的 Markdown 语法——标题、列表、代码块、表格、任务清单。底部有一排格式工具栏,不用记语法也能快速排版。

Markdown 编辑

多媒体附件

图片、视频、文件都能上传。图片会在备忘卡片里内联显示,视频支持全屏播放,其他文件类型以附件芯片形式展示,点击即可下载。

编辑已有备忘时,之前上传的附件也会正确显示在预览条里——这个看似理所当然的功能,实现起来其实踩了不少坑。

详情页

社区互动

如果你和朋友共用一个 Memos 实例,「发现」页面可以浏览所有人的公开备忘。支持 Emoji 表情回应和评论。轻量级的社交功能,不喧宾夺主。

发现页

多种登录方式

支持两种登录方式:

  • 用户名密码登录 — 最传统的方式
  • Access Token 登录 — 适合 OIDC/SSO 用户,在 Memos Web 端生成一个 Token 就能登录
登录页可选版本

真正的难点:三版本兼容

如果你关注 Memos 的开发,你会知道它的 API 在版本间变化很大。这里「很大」不是客气话——我列几个例子:

功能v0.24v0.25v0.26
资源上传端点/api/v1/resources/api/v1/attachments/api/v1/attachments
用户统计users/{id}/statsusers/{id}:getStatsusers/{id}:getStats
访问令牌路径access_tokensaccessTokenspersonalAccessTokens
枚举序列化数字 (1, 2, 3)数字 (1, 2, 3)字符串 ("NORMAL", "ARCHIVED")

连登录流程都完全不一样:v0.24 用 Query 参数 + JWT Cookie,v0.25 用 JSON body + Session Cookie,v0.26 又回到了 JSON body 但改用 Response body 里的 Access Token。

Memosly 同时兼容这三个版本。 登录时选择服务器版本,之后所有 API 调用都会自动走对应版本的分支逻辑。不管你的服务端停留在哪个版本,装上就能用。

这也是这个项目最花时间的部分——功能开发可能只占 40%,版本兼容和边界情况处理占了 60%。


一些有趣的技术细节

既然是投稿少数派,聊点实现层面的东西,可能对同样在做 Android 开发或对接 REST API 的朋友有参考价值。

gRPC-gateway 的 base64 陷阱

Memos 的后端用的是 gRPC,通过 gRPC-gateway 暴露 REST API。一个容易踩的坑是:文件上传不是 multipart form data,而是 JSON body,文件内容用 base64 编码。 因为 gRPC-gateway 会把 protobuf 的 bytes 字段自动映射成 base64 字符串。

如果你按照常规思路用 @Multipart 去上传,服务端会直接返回 400。

Android 进程死亡与 Token 恢复

Android 系统会在内存紧张时杀掉后台进程,但 Navigation 组件会恢复回退栈。这导致一个隐蔽的 Bug:App 被杀后重新打开,直接跳到主页面(跳过了登录页),但内存里的 Token 已经丢了,所有 API 请求都会 401。

解决方案:Token 管理器在构造函数里就从持久化存储恢复 Token,而不是等到某个页面触发时才读取。这个模式适用于所有「内存单例 + 认证状态」的场景。

视频附件不走 Markdown

Memos 的 Web 端对图片和视频的处理方式不同:图片用 ![](url) 嵌入 Markdown 内容,但视频不嵌入 Markdown,而是通过独立的资源关联 API 绑定。

这意味着你不能用正则从 Markdown 内容里解析出视频附件——必须用 API 返回的 resources 列表。这个坑我踩了一次,希望后来人能绕过去。


体验与设计

  • Material You 设计语言,支持 Android 12+ 的动态取色
  • 深色模式 跟随系统
  • 两种导航风格:底部标签栏侧边抽屉,设置里切换
  • 中英双语,跟随系统或手动指定
  • 下拉刷新、分页加载、相对时间戳

没有花哨的动效,就是一个用起来顺手的工具 App。

设置页
搜索

下载与参与

下载安装:

加入内测:

  • 如果你愿意帮助我尽快上架,可以私聊我你的 gmail,不甚感激!

反馈问题:

反馈时请注明你的 Memos 服务端版本(v0.24 / v0.25 / v0.26),这对排查问题帮助很大。

源码: github.com/whtis/memosly-android


写在最后

做这个 App 的初衷很简单:自己用 Memos,手机上需要一个好用的客户端,没找到合适的,就写了一个。开源出来,是因为 Memos 社区本身就是开源精神的产物,我也想把这份便利分享给更多人。

如果你也是 Memos 用户,欢迎试试 Memosly。用得顺手的话,去 GitHub 点个 Star 就是最好的支持。

3
0