Notion Blog
我把完整的 Linux 容器和 OpenCode 塞进了一个 75MB 的 APK,Android 变身真·AI 生产力工具
技术分享1 分钟阅读

我把完整的 Linux 容器和 OpenCode 塞进了一个 75MB 的 APK,Android 变身真·AI 生产力工具

我把完整的 Linux 容器和 OpenCode 塞进了一个 75MB 的 APK,Android 变身真·AI 生产力工具

先说结论:一个 75MB 的 APK,装完手机就是完整的 AI 开发环境——跑 Linux、写代码、调模型,全套都有。不用 VPN,不用 API Key,连 WiFi 就能干。

起因:手机里的编程体验太差了

用 opencode 的都知道,手机上想跑 AI 编程助手有多痛苦:

没有 git?没戏
没有 Python?跑不了脚本
没有 Node.js?装不上依赖
装了也跑不起来,因为 Android 底层是 bionic libc,Linux 二进制根本不兼容

之前试过各种方案:打包单个二进制 → 再打包 git → 再想办法塞 Python... 每多一个工具就多一层兼容问题,像个漏水的桶。

直到有一天:干脆整个 Linux 塞进去得了。

方案:把 Alpine Linux 塞进 APK

不是跑个容器模拟器,是真的把 Alpine arm64 rootfs(完整文件系统)打包进 APK,用 proot 跑起来——一个完整的 Linux 环境,能 ls、能 apk add、能跑任意脚本。

[table]

从 v1 到 v3 的教训:别折腾单个二进制,整环境。

但 Android 不是 Linux,塞进去跑不起来

这才是真正硬的部分。Alpine 容器跑起来后,一个接一个的坑:

坑 1:libc 不兼容

Android 用 bionic libc,Alpine 用 musl libc,系统层面根本不认识对方。

解决:所有二进制改用 musl 编译,自带 musl loader(ld-musl-aarch64.so.1),不依赖系统任何 libc。

坑 2:ELF 加载器路径写死了

内核执行二进制时,会去 PT_INTERP 段指定的路径找 loader。但那个路径编译时就写死了,在 Android 上根本不存在。

解决:用 patch 把路径改写到 app 私有目录里 loader 的真实位置。

坑 3:SELinux 不让执行

Android 10+ 的 SELinux 策略只允许从 nativeLibraryDir 执行文件。普通文件放 files/ 目录,系统直接拒绝执行。

解决:主二进制伪装成 JNI .so 文件放在 nativeLibraryDir,其他文件放 assets 解压到 app 私有目录。

坑 4:没有 DNS

musl 解析域名依赖 /etc/resolv.conf,但 Android 系统里这个文件不存在。

解决:运行时重写 DNS 配置,让 musl 能正常解析。

坑 5:锁屏就死

Android 对后台进程越来越狠,锁屏后没几分钟就被系统回收。

解决:前台服务 + 持续通知 + PARTIAL_WAKE_LOCK,锁屏照样跑。

装完之后长什么样

75MB 的 APK,装上之后:

Alpine Linux 完整容器:ls / cd / apk add 全支持
OpenCode AI 助手:写代码、读代码、跑脚本、调 Git
Node.js + Python + Git:开发三件套,不缺一样
内置免费模型:内置免费模型,零成本
项目在 /sdcard/opencode:文件管理器直接访问
锁屏后台保活:不占用前台,不影响刷视频

技术上最值钱的几点

•
musl + PT_INTERP patch:这是所有 Linux 二进制在 Android 上跑起来的前提,没有这一步一切免谈
•
SELinux 绕过:伪装 .so 是个很野的 trick,但它是唯一能在不需要 root 的情况下执行文件的方案
•
完整容器 vs 二进制补丁:选容器这条路后,后面所有问题都变成了「容器里怎么配置」,而不是「怎么让 Android 系统接受这个东西」

代码 & 下载

APK:GitHub Release 下载,tag 格式 vA.B.C

有想法 / 踩坑 / 想交流,欢迎评论区留言 👇

读者评论

评论会同步写入该文在 Notion 中的页面底部(与正文同页,便于管理)。

0/1500

暂无评论,欢迎抢沙发。