Try Mobile Development
一段业余尝试移动开发的经历。
大概是24年8月,也就是去年的这个时候,为了对抗目标缺失感(goalless),强迫自己去学点什么。从点开一个有点印度口音老哥的 Flutter 入门视频一个个拖进度条看完,到动手做出了几个简单的 APP, 再到今年5月后基本没有再投入精力,历时大半年的时间。最近经常在回想这些事情,干脆总结一下,可能会比较乱想到哪里写到哪里。
项目概要
按时间顺序。
AI Client - Yaaa(Yet Another AI Assistant)
第一个做的是一个 Chat Client APP, 封装 API 调用各大模型,能够调 prompt,本地保存数据。其实这个想法在 23 年初就冒出来了过,当时也没有任何移动开发经验,在疫情放开后的短暂 gap 期间尝试了一下 iced / dioxus 这样的 Rust GUI 框架,还是太年轻,这些框架太不成熟,再加上我还是菜鸟,不说 markdown 编辑器了,连一个能用的多行输入框都很难搓出来,最后又上班了就不了了之。
当年关注到一个开源的 ChatBox 项目后面也是大火。但是开源社区运营了一段时间开始实际闭源 + 卖付费订阅了,诱惑很大可以理解但不太认同。
还是想要做一个属于自己的,能用就行,搜了下也没有用 Flutter 写的。正值 DeepSeek 发布了 V2,随后 V3 也出来,整合 chat/code 了,大模型的 API 价格被国内厂商打下来了,正好来做做。
实现了一个完全本地数据的 Chat Client,配置自己的提供商和 key(deepseek接口和openai一样,大多数都还是在follow openai的,这点很好),编辑保存不同的 prompt/参数 作为 Assistant,基于 Assistant 创建对话,能够搜索历史,对话重置,win端还做了一些常用的快捷键。
第一个项目第一次遇到打包和发布问题,windows 端用 inno setup 打包成 exe 安装包,很简洁好用配置一次就好了。android 端 flutter build apk
看着很简单,但是安装了就会遇到了诸如证书问题、正式版本的应用权限问题、SDK 版本问题等一堆故障。配置文件也是五花八门,印象深刻国内还有连 oracle 的网络问题。从没写过 Java 的我也是淌了不少坑,最终也没完全理解 sdk/gradle 的许多问题,也是能打包分发了。感觉商业包袱历史包袱太重了,整个过程体感极差,个人很不喜欢。但为了能在手机上用原生应用,不得不配合这套规则。
用上了 AI 生成 APP Icon,白嫖大善人的 r2 做图床放了一些静态资源,不快但是能用。学了一点字体的基础知识,用上了一个名字也很美的中文开源字体,叫 lxgw,落霞与孤鹜齐飞。
初学做 APP 真的很有意思也很有成就感。
笔记 - xbb
第二个做了一个笔记应用,Markdown 编辑渲染,按仓库分类保存,支持分享仓库给他人订阅,并写了一个配套的服务端来实现云存储和多端数据同步。
后端 web 框架用了一个国人开发的 salvo,很喜欢其表达的简洁性,适合这种小项目。
数据库继续用 sqlite,dart/rust 都有很好用的库支持。
课表记录 - daydayup
这个需求是年后跟姐姐聊天时提出来的,她说她们宝妈们根本找不到一个好用的 APP 给孩子补习班做记录,弄不清楚机构到底有没有多扣除课时费用。跟“客户”沟通了个把小时,梳理清楚了她们的需求,花了大概三周开发出来了。
场景是填入课程的上课,软件自动排列出后续的课程,支持日历/列表/范围查看等。如果实际缺课再手动标注。
日历组件、选择器这些组件找到了十分好用的三方库,丝滑流畅,感谢开源社区。
记得最让我头疼的问题有两个,一个是时间的处理,区分日期和时间,时区的处理,每周几、每双周这种间隔逻辑,不难但是有些费脑。另一个就是动态排课逻辑,身兼产品设计和开发,在这里陷入了一段没有明确需求就开发的泥潭,我记得有个周末的下午我左右脑互搏了很久。也是这个项目结果里自己对自己最不满意的一部分,定义好边界和用户场景再开发是很重要的。
桌游复刻 - planetx
这是一个今年玩的一个桌游 The Search for Planet X 的复刻线上项目。玩家需要在一片随机生成但有一定规律的星图里,使用各种手段获取线索和信息,获取分数并逐步缩小范围定位到那个神秘的目标行星 X。猜测其它玩家的行动和意图也是游戏很有意思的一部分。记得线下玩了三四把保持着 100% 首猜且正确(虽然总分上可能没赢),那段时间有点上头。
线下需要纸笔同时也需要一个网站来做后台的地图生成和猜测验证,这太适合做一个在线版本了。于是就有了这个项目。
先快速验证了一下地图生成的算法(类似开放世界种子生成)是可以写出来。然后研究了下前面项目都没接触过的 socketio,因为必须要实现服务端到客户端的通信,需要自动更新状态。
扇形分块的星图在AI帮助下很快就能把坐标计算代码撸出来,好像也没花两周就弄出来了第一个可对战版本。前端用 github page 部署了 Web 版本,买了个域名研究了下 cf 的后端转发功能。
上线 Web 版本还有个加载大小问题,比如静态的字体文件太大了、找了个python工具挑选出其中的常用字集,减少了 90%+ 的大小。(冷知识,彗星的彗字,不在3500常用汉字里)
后面想着开发一个bot来和人对战,bot 依据最简单的贪心逻辑,穷举所有可能的行动和预期结果,根据预期结果对降低当前可能总数的效果进行评价,选择平均每动最优的那个。这个算法需要遍历所有可能的星图,在困难模式18个扇区的情况下,总数是百万级别的可能数(中间甚至发现了发行商写的博客资料里,这个可能数是错误的),所有可能数在后端需要占用 20 MB内存,不过会在一两步之后就快速下降到忽略不计了。
就这么一个完全不考虑其它玩家行动,仅根据客观事实挑选一个依据我随手写的评价函数里最优的行动,在我假装不知道它的行动逻辑以此获取额外信息的情况下,bot 大多数情况下都能赢过我,在绝对的算力压制面前,人类直觉的评价函数确实太弱了。
虽然整体玩的时间 << 开发时间。后端现在大概也挂了(好像是 cf 转发的 proxy 问题,换了个服务器后不记得咋配置了就没折腾)
收获感受
AI Client 帮助我加速了日常工作里的重复性工作,调教好一些 assistant(prompt),轻度使用的API花费几乎忽略不计,效果比开一个网页端也好很多,还自带分类归档效果。
XBB 用来记录分享日常生活,不同于即时通讯工具,这种订阅分享和无需明确回复的方式,让我和异地伴侣的分享变得更多,记录下生活的点滴。
想把这些项目再打磨一下,不过目前还找不太到动力,最后一个可以作罢,前两个日常每天用,之前还有个想法时是结合起来,笔记可以变成 RAG,再加上一个智能剪贴板的功能自动归档每日剪贴板内容。 课表也有想法做成一个 Web 版本,解决打包发布更新的问题,也能支持更多平台(有浏览器就行),但是就需要长期持续的维护成本了。
原生应用 vs Web
Flutter 跨平台支持得还是很好,一套代码主体,写少量平台特定的代码就可以实现不同平台的适配。
但是!能写出来到能给用户用之间还隔了很远。真的想让普通人能随时下载你的 APP,就不得不玩苹果谷歌微软以及国内应用商店它们的游戏。对于一个早期学习的开发者,直接被苹果一年99美元的开发者账号劝退(买一年 Copilot 也才这个价格)。
好在除了 Apple 家的根本无法分享,其它平台还是可以通过各种方式打包出来,自己分发“包含不被信任的证书”的应用。虽然存在不方便,但至少可以让自己和身边人用上,开源在 Github Release Pages 上也能分享,项目本身代码开源再用 action 打包也是一种足够被“信任”的方式了。
所以后面的项目尝试了下 Web 版本,完全没有这些证书、发布更新的问题,版本可以全部由服务端控制来更新。但是会存在的缺点是性能和用户体验可能不如原生应用那么好;以及如果是有状态且业务上并不需要联网的 APP,也不得新增一个后端服务来存储,你总不能依靠不靠谱的本地缓存来实现;同时也还是需要购买一些域名和服务器来部署。
所以后续如果继续做些独立小项目,如果可以肯定会更加倾向于先只做 Web 版本。不过 flutter 的 web 性能问题如果不解决,可能还是需要切换到其它语言/框架。
不要重复造轮子
可以造轮子,但是不要重复造轮子。我始终相信任何“新”的尝试都是有意义的,弯路只是让到达目标的路程远了,后续不断优化迭代工具链就好。
体验过手搓一个 picker 才能更好地用上现存的三方库。
AI
在 AI 的帮助下,能力可以很快速的外延到新的领域,对特定领域的熟练度的壁垒很容易被打破,一些通用的工程思维反而更加重要。