夜雨聆风学习资料网

ARTICLE · 1336703

把 Mika 源码读了一遍:它凭什么能替你操作手机

把 Mika 源码读了一遍:它凭什么能替你操作手机

最近这几天,一个叫 Mika 的安卓项目在开发者圈子里传得挺快。10 月 29 日开源,两天时间就到了 3000 多星、500 多个 fork。

图源 Mika github 官方仓库

它解决的是一个我们都很熟悉、却一直没被解决好的问题:让 AI 直接操作你手机上的 App。

微信、小红书、BOSS 直聘、银行 App——它宣称不用给这些 App 做任何适配,就能替你操作。而且它还有个听起来更玄的能力:手机里跑一个本地 Linux,能执行 Python,不需要 root,也不需要连电脑。

这类项目常见的两种命运是:演示惊艳、实际不可用;或者只在几个特定 App 上做了硬编码。所以我把它源码完整读了一遍,想搞清楚三件事——

• 它到底实现了什么功能,边界在哪;

• 这些功能是怎么实现的,哪些是取巧、哪些是真功夫;

• 从实现方式里,能不能看出更多它自己没说的局限。

下面按这个顺序讲。全篇只基于源码阅读,没有在真机上跑过它。

它对外宣称的四件事

先把宣传口径摆清楚,后面逐条对账:

• 操作任意 App,免预适配

• 内置浏览器

• 悬浮胶囊,随时唤起

• 本地 Linux 沙箱,免 root、不需要电脑

一、agent们撞上的那道墙

理解它的做法,先得知道它撞的是什么墙。

在安卓上,一个没有 root 的普通 App,有三件事干不了:不能凭空建一块屏幕、不能往别的 App 里塞点击、不能读别的 App 的界面。

不巧的是,这三件正好就是「替你操作手机」所需要的全部。

Mika 的解法不是提权,而是借系统自己的调试通道:你在开发者选项里打开「无线调试」,配对一次,Mika 就能以 adb shell 的身份跑起一个自己的助手进程。

这句话的分量要说清楚。adb 是安卓官方的调试接口,原本是给开发者连电脑用的。它不等于 root,但能做的事远远超过普通 App:建屏、注入输入、跨资料启动、改一部分系统设置。

所以严格讲,Mika 手里不是「超级权限」,而是「一个 shell」。 这一步是后面所有事的前提。

这里有两个反直觉的点值得单独说。

一是它不需要电脑,也不需要数据线。 「无线调试」是安卓自带的开发者选项,配对全程在手机屏幕上完成。数据线接电脑那条路是备选方案,而且每次重启手机都得重来一遍。

二是它连的是它自己。 Mika 没有调用 adb 命令,也没打包 adb 程序,而是在 App 内部自己实现了一整套 adb 协议客户端——连接、配对、密钥、加密都是它自己的代码。它连的是本机回环地址:同一个 App 既当客户端、又当被连的那台「设备」,流量根本不出手机。Wi-Fi 只用来发现端口号,不承载操作指令。

二、五步链路:从拿到权限到点下去

整条链是这样的:

第一步,拿身份。 就是前面说的,借无线调试拿到 adb shell 身份的助手进程。

第二步,开一块不存在的屏幕。 由 shell 身份让系统建一块虚拟屏,它不属于任何物理屏幕,画面直接流回 Mika 自己的进程。好处有两个:截图不用走无障碍的截屏接口;而且你手里的主屏全程不受影响,该刷什么刷什么。

第三步,把 App「搬」过去,而不是「装第二份」。 这是最容易误会的一步。它没有克隆 App、没有双开、也没有改包,而是让 App 的原有实例显示到那块虚拟屏上——同一个包名、同一个安卓用户、同一份数据,只是窗口出现在另一块屏上。

这一点带来一个很重要的副产品:它天然继承了你的登录态。 你不需要把账号密码交给它,它用的就是你已经在用的那个 App。

启动前它还会先查一下:你是不是正在主屏用这个 App?如果是,就不启动,免得把你在看的界面挪走。很小的一个细节,但说明作者在想「用户此刻在干什么」。

第四步,怎么「看见」。 主力是读系统的无障碍窗口树,拿到每个控件的文字、位置、能不能点。界面全是自绘、控件没名字的时候,用随安装包一起打包的本地 OCR 认屏上的字。再不行、而且你配了会看图的模型,就让模型直接在画面上找按钮。

第五步,怎么「动手」。 三条路:点已知控件、在指定屏上点坐标或滑动、模拟按键(回车、返回)。

有个设计值得注意:执行前会重新定位一次目标。 界面变了,之前拿到的引用就作废,所以它不会照着旧坐标点错地方。

三、免适配的本质,是绕开了适配

为什么它不用给每个 App 写插件?

因为它模拟的是「一个人看屏幕、找控件、点下去」这个回路。任何 App 想在安卓上被看见,就得把界面画到系统屏上;想被操作,就得接收系统的输入事件。Mika 站在这两层系统接口上。

它不需要 App 配合,因为它用的就是系统给所有人的那套接口。

这不是「适配了所有 App」,是「绕开了适配这件事」。

四、从实现里看出的局限

源码读到这里,局限其实已经自己浮出来了。下面这些不是「作者没做好」,而是这条路本身要付的代价。

第一,通用性是用「不确定」换来的。 自绘界面只能靠 OCR 和看图猜,成功率比原生控件差一截;银行、支付这类受保护页面会被系统标记为不可读,它根本碰不到;系统接口一旦变化、或者厂商定制过,就可能失效。它没有走「给 App 写插件」那条确定的路,就得接受这条路上的手感波动。

第二,「看见」和「会做」是两件事。 它能读懂屏幕上有什么,但不知道这个按钮点下去会发生什么。所以它只能一步步试、错了再退回来。这就是为什么这类项目在短任务上演示很流畅,任务一长就容易跑偏。

第三,两条支线其实互不相干。 这是个特别容易混的点,很多人以为「能跑 Linux」是它操作 App 的基础。不是的。

手机 App 从头到尾跑在安卓里,从来没进过那个 Linux。沙箱是另起的一条线,目的只是「给模型一个能跑 Python 和命令行的地方」,默认还是断网的,文件进出走固定关口。两条线唯一的交汇点:脚本可以反过来请求手机去点 App——但真正动手的,始终是安卓那块虚拟屏。

第四,它里面的「沙箱」不等于安全隔离。 有断网过滤、有文件关口,但它和主程序同属一个安卓用户、没有独立内核边界。所以它的定位是「受限的本地计算环境」,不是「能放心跑陌生代码的隔离层」。

第五,默认策略比模块名字更重要。 代码里有风险分级、有审批策略、有确认门,看着挺齐全。但实际默认行为是:只有「付款」会弹确认,普通的发送、提交、删除直接执行;如果开了自主模式,连付款都不问。而且任务一旦跑起来,再把自主模式关掉,对当前这个任务也没用了,要等下一个任务。

最后一件:进程被杀之后,它只做善后通知,不会从中断的地方接着跑。

五、它能做什么,不能做什么

把上面这些收成一张图更直观:

一句话概括边界:

• 相对稳的:操作你已登录的 App(原生控件界面)、读界面文字、点按钮、填输入框、在内置浏览器里查资料翻页、在沙箱里跑 Python 脚本。

• 明显吃力的:自绘界面、密密麻麻的列表、银行支付这类受保护页面、需要你本人到场的验证码和刷脸、以及「从头稳定做到尾」的长链条任务。

这也是为什么作者自己把项目定位在早期测试版、并且主要只在一台 Android 14 手机上测过。

六、这件事给做 AI 助理的人的启发

抛开 Mika 本身,这条路线值得琢磨的地方有三点。

第一,「绕开适配」是个正确的大方向。 只要 AI 要操作真实世界的软件,就不可能靠一个个写插件追完。站在系统通用接口上,是唯一能规模化的路子——代价是精度和稳定性。

第二,真正难的不是「点得准」,是「知不知道自己点对了」。 Mika 绕开了坐标精度问题,但绕不开「结果验证」问题。谁能把「这一步到底成功了没有」判断准,谁才能真正把长任务做稳。它在这件事上目前是缺的——产品里最终核查是关掉的。

第三,授权边界要讲人话。 配对一次无线调试,用户以为自己只是「开了个调试开关」,实际上给出去的是一个 shell。这个信息不对称,是这类产品都要面对的问题。

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料