同一段视频 9 种压法:设得越「清楚」,文件反而越大
同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。

结论先放这:这台服务器上没装 Android Studio,也没有 Gradle,我用七个命令行工具,把 16 个 Java 文件打成了一个 85KB 的安卓安装包。手机上能装,名字和图标都正常。
机器只有 2 核、内存不到 2GB。Android Studio 是一整套图形界面。
Gradle 第一次打包还要再下几百 MB 依赖,这台机器扛不住。
我要的东西很小:一个能装到手机上的小程序,界面用代码画,不引别人的库。所以走手工路线。
工具只用官方那一小包,一共七个,顺序不能换。
核心就是这段脚本(节选,能直接跑):
BT=/opt/android-sdk/build-tools/34.0.0
PLAT=/opt/android-sdk/platforms/android-34/android.jar
mkdir -p build/gen build/classes build/dex
$BT/aapt2 compile --dir res -o build/res.zip
$BT/aapt2 link -o build/base.apk -I $PLAT --manifest AndroidManifest.xml \
--java build/gen -R build/res.zip --auto-add-overlay \
--min-sdk-version 24 --target-sdk-version 34
javac --release 8 -encoding UTF-8 -cp $PLAT -d build/classes \
$(find build/gen java -name '*.java')
$BT/d8 --lib $PLAT --min-api 24 --output build/dex \
$(find build/classes -name '*.class')
$BT/zipalign -f -p 4 build/unaligned.apk build/aligned.apk
$BT/apksigner sign --ks mn.keystore --ks-pass pass:android \
--out jizhang.apk build/aligned.apk
每步花多少时间、包涨到多大,实测是这样:
从空目录到能装的包,一共 11.0 秒。慢的是 javac 和 d8 这两步,加起来 9.5 秒,占了大头。
包为什么这么小?我拆开数过,整个包里只有 11 个条目。
没有 lib/、没有 assets/、没有 androidx,也没有一行 WebView 代码。85KB 里绝大部分是自己写的逻辑,dex 那 153,660 字节压缩后就是剩下的那点。
签名那一步不能省,安卓系统只装签过名的包。签名就像给包贴一张封条:证明是你发的,别人改过一个字节,手机就拒装。
装到手机上要在设置里允许"安装未知来源的应用";这个包最低支持安卓 7.0(代号 API 24)。
坑一:d8 不会自己建输出目录。我这次重跑就撞上了,报错原文是:
Error: Invalid output: dex
Output must be a .zip or .jar archive or an existing directory
补一句 mkdir -p build/dex 就过。
坑二:aapt2 link 出来的 base.apk 里没有代码。它只有 6,562 字节,是个空壳。
必须自己把 classes.dex 追加进去。不塞的话,装上打开就闪退。
用 python 的 zipfile 以追加模式写进去最省事,不用解压再重打。
坑三:版本号以清单文件为准,命令行写的不算。我实测过:AndroidManifest.xml 里写的是 versionCode 17、versionName 1.6.5。
我再加上 --version-code 1 --version-name 1.0 重新打包,查出来还是 17 和 1.6.5。清单文件相当于这个包的身份证,优先级更高。
后果很实在:发出去的新包,手机上的安装器以为还是老版本,不提示更新。
坑四:对齐要在签名前面。zipalign 会移动包里文件的位置,签完名再对齐,签名立刻失效。
顺序固定是:塞 dex → 对齐 → 签名。
坑五:签名只认 v2 就够了。apksigner verify -v 里 v1(旧的 JAR 方案)显示 false,v2 和 v3 显示 true,这是正常的。
最低版本写 24 以上,系统认 v2,不用为 v1 折腾。
坑六:字节数和 md5 都不能判断"包是不是新的"。我这次重编出来的包,和上一版打出来的包字节数一模一样,都是 86,762。
但 md5 不同(a66dbb2f2fd0… 对 1f4d8346ae05…),因为 zip 里存了每个文件的修改时间,重编一次它就变。
体积一样不等于没改动,md5 变了也不等于改动生效。要证明新代码真进包,直接查 dex 字节:
python3.12 -c 'import zipfile; d=zipfile.ZipFile("jizhang.apk").read("classes.dex"); print(b"你新加的字段名" in d)'
下次注意三件事:把 mkdir -p 写进脚本第一行;版本号只在 AndroidManifest.xml 里改一处;每改完一版先装到手机上点一遍,再对外发。
同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。
同一张壁纸 674.9 KB 能压到 122.9 KB,站上 15 张配图省到四分之一
三个老推送接口都死了,我用 IndexNow 把新文章推给搜索引擎