有没有受 Android 工程编译慢困扰的老安卓,推荐个我自己做的方案

sickworm 2026-07-23 13:15 1

背景是这样的,21 年的时候我突然灵光一闪,想着“如果我编译的文件足够少,应该要编译的足够快”,然后在 3 个月肝了一个 MVP 出来(还拿去答辩通过了)。
这是当时录的 视频。


方案核心是用了三个黑魔法:



  1. 源码编译只用 javac/kotlinc 编单个文件;

  2. 资源编译用 aapt2 ,但被我改成了支持增量 link 的定制版本;

  3. 部署会优先走 Android Studio 的 Apply Changes ,可以热重载;
    这一套下来耗时可以压在 3 秒内。


不过当时基本只是个玩具,动不动就失败崩溃。而且当时公司比较流行把工程放到云服务器编译,只拉 apk 下来,导致我这个需要本地 build 产物的方案不太好落地。后面就是 2 年断断续续的沉沦和奋起,反正没有占上班资源,都是自己下班时间搞,所以也没 KPI 。


直到 23 年我突然想到(有点晚)可以用 rsync 把文件也拉到本地,所以又奋起了一波,在 23 年终于做了个 v1 版本,给组内同学开始试用起来。后面老板也给力帮忙推了一波,人开始渐渐多了起来,继续疯狂迭代了 2 年(一年 1000+ 个 commit ),迭代到现在已经挺稳定了。


简述插件优势就是:



  1. 平均 3s 编译耗时(需要先 gradle 编译一次生成产物,改源码增量,改 gradle 文件重新降级);

  2. 直接装 IDE 插件就能用,不用改工程;

  3. 磨了 5 年,公司内部推广了 2 年半,接了十来个生产工程,编译了 80W 次(插件有个编译次数的上报),已经比较稳定了。


今年想走公司仓库开源,估计就是这两个月的事情。目前还没开源,但插件可以直接下载用。我在外网放了一份,看看有没有感兴趣的老哥试用一下,提前给点反馈。接入文档

最新回复 (43)
  • luckyc 07-23 13:26
    1
    卧槽, 大佬.
  • superkkk 07-23 13:26
    2
    我习惯用 github 的 action 流水线自动编译,就是很慢,让 ai 帮忙改配置文件就行了,自己本地不用搭建一坨安卓的环境
  • sickworm 楼主 07-23 13:41
    3
    @luckyc 🧎‍♀️
  • sickworm 楼主 07-23 13:43
    4
    @superkkk 我们这暂时还没法全走云端,不过也是迟早的事情。到时候不知道我这方案还能不能继续产生价值,万一 ai 干啥都是 one shot 都没有调试的事了
  • BestEicky 07-23 13:44
    5
    真大佬啊,就是这个下载太慢了,6kb/s
  • WebKit 07-23 13:53
    6
    就不能直接放个 github 或者其他不需要登录的文档吗
  • sickworm 楼主 07-23 14:13
    7
    @WebKit 抱歉了,因为后面打算换个组织开源所以仓库目前是私有的没法访问
  • sickworm 楼主 07-23 14:15
    8
    @BestEicky 我这是阿里云 100M 水管,奇怪了,其他人暂时没遇到
  • SuperLino 07-23 14:44
    9
    用起来了,神器! Android 终于有了类似 web 的开发体验! nb
  • NathanDo 07-23 14:47
    10
    所以这个插件必须依托 Android Studio 吗? 能不能让 AI 通过 command 使用
  • sickworm 楼主 07-23 14:54
    11
    @SuperLino 卧槽这么快,欢迎提意见
  • sickworm 楼主 07-23 14:56
    12
    @NathanDo 做了 agent 能力,已经支持 cli 调用了,但本质还是调去 android studio 的插件 runtime 。不打开 android studio 的纯 cli 不少人也有诉求,正在做
  • sickworm 楼主 07-23 14:56
    13
    @NathanDo 接入文档最下面有个使用介绍
  • hlayk 07-23 14:58
    14
    试了下很强 问一下例如要发正式版本了 是不是主动降级 Gradle 编译 然后在打包 这样安全些?还有这个主动降级和 Build->Clean project / File Invalidate Caches 有什么关系吗?我为了完全重新编译是不是还是 点击一下 File Invalidate Caches 更稳妥?
  • sickworm 楼主 07-23 15:05
    15
    @hlayk 感谢关注,回答一下
    1. 插件是 for debug 的,发正式版本不要用,首先默认情况下增量文件是保存在设备的,apk 不含增量变更;其次 release 包混淆后情况变得非常复杂,不可靠
    2. 主动降级是命令行运行 gradle 进行编译 e.g. ./gradlew :app:assembleDebug (会从 IDE 读具体的命令),把 gradle 产物刷一遍
    3. Build->Clean project 会把 gradle 产物清掉,插件会自动失效,需要降级一次
    4. File Invalidate Caches 只清理 IDEA 的缓存,对插件以及 gradle 都无任何影响
    5. 完全重新编译 clean 就够用了,产物都删掉了
  • hlayk 07-23 15:12
    16
    @sickworm 我刚刚试了下 打包选择 AAB 或者 apk 里面选 release 也是几秒就出结果了 发正式版如何关掉插件?
  • kalixi 07-23 15:15
    17
    我连连接了几台手机,run 一下,给每一一台都轮流装了,选择设备以及无效了,神奇
  • zy0829 07-23 15:27
    18
    我可不可以理解为这就是热更新
  • sickworm 楼主 07-23 15:35
    19
    @kalixi 收到,我试试
  • sickworm 楼主 07-23 15:38
    20
    @hlayk 不运行 jugg:* 的配置就可以了,右上角 Run Configuration 切换回 Android 的运行配置
    你说的打包应该是完全不走插件的

    总结就是没有黑魔法 - 只有选了 jugg:* ,点击 Run/debug 按钮才会走插件的编译,其他任何 Android Studio 操作都不侵入
  • sickworm 楼主 07-23 15:47
    21
    @kalixi 确认了是真的,quail 1 的行为变了,今天修一下
    我一直用的 panda4 ,quail 1 不好用适配完就没用了,没注意到这个变化
    感谢
  • sickworm 楼主 07-23 15:50
    22
    @zy0829 是的,目前有两条路子,一个是用 jvmti 接口插入增量变更,另一个是 application 初始化时反射改 dex 和 res 资源列表
    目前插件都支持,第一个优先,第二个兜底
  • stucom 07-23 16:37
    23
    很感兴趣,我就做 Android App 开发的,期待大佬开源~
  • 0x0x 07-23 16:54
    24
    1. 确实多个设备会尝试一个一个安装。我有一个 offline 的模拟器,也去尝试安装了。 然后提示因为 offline 失败。

    2. 实际上是 Android 16 ,不知道是不是这个降级原因,导致我感觉没有正常的编译快,我只改 xml 的情况下,原生编译 5s ,用插件 28s
  • zhanxicai 07-23 16:59
    25
    试了,真的很快,🐂🍺
  • hanfly19 07-23 16:59
    26
    Android Studio Quail 1 | 2026.1.1 Patch 2
    第一次编译之后,每次都会报 R 文件找不到,然后点击 「 Fallack to Gradle 」 可以编译成功但是时间很长。
  • qq2511296 07-23 17:30
    27
    请问对 Flutter 项目也有帮助吗?
  • xoliu6 07-23 17:42
    28
    牛啊,看前边原理挺眼熟的,当时还有幸看代码学习过。看到后边名字发现是大佬的东西,👍这个确实好用,现在也一直在用,debug 省很多心力了
  • SmallAn 07-23 18:10
    29
    学习一下👍
  • sickworm 楼主 07-23 18:35
    30
    @xoliu6 太好了
  • iFlicker 07-23 18:35
    31
    Android Studio Narwhal | 2025.1.1
    可能项目比较复杂, 用了一下报错 NoClassDefFoundError
    java.lang.NoClassDefFoundError: Failed resolution of: Lcom/xxx/xxx/xxx/xxx/R$id;
    Caused by: java.lang.ClassNotFoundException: Didn't find class "com.xxx.xxx.xxx.xxx.R$id" on path: DexPathList[[dex file....
  • sickworm 楼主 07-23 18:36
    32
    @qq2511296 flutter 源码不行,flutter 项目用 android studio 打开,修改 android 源码可以
    不过 flutter 自己的热重载不是挺好用的么
  • sickworm 楼主 07-23 18:39
    33
    @hanfly19 方便的话双击 shift 搜 report jugg issue 反馈下日志,或者加我也可以 Y2hlbmhhb3Nj
  • sickworm 楼主 07-23 18:39
    34
    @iFlicker 方便的话双击 shift 搜 report jugg issue 反馈下日志,或者加我也可以 Y2hlbmhhb3Nj
  • sickworm 楼主 07-23 18:43
    35
    @stucom 第一时间通知你
  • hanfly19 07-23 18:46
    36
    @sickworm Jugg report ID: 3c2640ec
    Server: http://sickworm.com:12305
  • sickworm 楼主 07-23 19:06
    37
    @kalixi 感谢反馈,Quail 选择所有设备的问题修复了,更新方式:双击 shift 搜 check jugg update
    或者下载: https://jugg.sickworm.com/download_page
  • sickworm 楼主 07-23 19:08
    38
    @0x0x 感谢反馈
    1. Quail 选择所有设备的问题修复了,更新方式:双击 shift 搜 check jugg update
    或者下载: https://jugg.sickworm.com/download_page
    2. 这个问题感觉很可能是 1 带来的,因为目前还没有过识别 API 出错的情况(用的 IDE 的信息),有空可以试试

    降级就是 gradle 命令行编译,不过应该是差不多速度才对,这个确实有点奇怪。不降级修改 xml 一般只要 500ms
  • sickworm 楼主 07-23 19:32
    39
    @hanfly19 感谢反馈,找到原因了,主工程和 includeBuild 的工程都有一个 application 模块而且是同名的,然后插件错误的选了 includeBuild 里的模块导致 R.jar 找不到

    已修复,更新方式:双击 shift 搜 check jugg update
    或者下载: https://jugg.sickworm.com/download_page
  • frantic 07-23 19:58
    40
    太强了,bro!!
  • kile 07-23 21:48
    41
    主宰!bro
  • RockOrRoll 07-23 23:05
    42
    Can't find apk "app/build/outputs/apk/testGoogle/debug/*.apk" in /Users/user/project/xxxx, please make sure your run configuration is right.
    Can't find apks in [app/build/outputs/apk/testGoogle/debug/*.apk] in /Users/user/project/xxxx by argument: "app/build/outputs/apk/testGoogle/debug/*.apk", please make sure your run configuration is right.

    大佬报了这样的错,可能是以为我这指定了 build 目录

    project.buildDir = "${rootProject.projectDir}/build/" + project.name
  • sickworm 楼主 07-24 09:56
    43
    @kile 哪里都有刀斯林
* 帖子来源V2EX
返回