ApkPatchLibraryServer

September 6, 2026 · View on GitHub

ApkPatchLibraryServer 是本地 Java + JNI 命令行工具,生成和应用与 Android 客户端兼容的 BSDIFF40 补丁。它不是网络服务,不包含固定 APK 路径。

环境

  • JDK 17
  • macOS 或 Linux
  • 系统 C 编译器(macOS 使用 /usr/bin/gcc,实际为 Apple Clang)
  • 项目自带 Gradle Wrapper

命令

在仓库根目录执行:

./gradlew :server:run --args='diff ../Apks/淘宝v10.65.10.apk ../Apks/淘宝v10.65.20.apk /tmp/taobao.patch'
./gradlew :server:run --args='patch ../Apks/淘宝v10.65.10.apk /tmp/taobao-rebuilt.apk /tmp/taobao.patch'

参数顺序固定:

diff  <old> <new> <patch>
patch <old> <new> <patch>

输入必须是存在、可读、非空的普通文件。输出父目录必须已存在且可写;为防止误覆盖, 输出文件必须尚不存在,并且不能与任一输入指向同一文件。CLI 只让 native 写同目录临时 文件,成功后才原子发布;失败或正常中断会清理临时文件,不会暴露半成品目标路径。

公开退出码:

退出码含义
0成功
64命令或参数数量错误
66输入路径无效
70native worker 加载或执行失败
73输出路径无效或已存在
124超时,worker 已终止

原始 bsdiff 实现会在部分错误上直接结束进程,因此 CLI 把 native 调用隔离到子 JVM,并将其非零结果统一映射为 70

构建与验证

./gradlew :server:clean :server:e2eTest
./gradlew :server:build

e2eTest 在独立 JVM 中生成确定性小文件,执行完整的 diff -> patch,逐字节比较结果, 并验证已有输出不会被覆盖、native 失败不残留目标或临时文件。distributionE2e 还会复制 installDist 到新目录,通过分发脚本再跑同一闭环。checkbuild 自动执行两套测试。

native 产物位于:

  • macOS:build/native/libApkPatchLibraryServer.dylib
  • Linux:build/native/libApkPatchLibraryServer.so

默认 JAR 主类是 com.cundong.cli.ApkPatchCli。native 库已打进 JAR,运行时会提取到 进程私有临时目录,因此 JAR 和 installDist/ZIP 均可整体搬运:

java -jar build/libs/ApkPatchLibraryServer-2.0-all.jar \
  diff ../Apks/淘宝v10.65.10.apk ../Apks/淘宝v10.65.20.apk /tmp/taobao.patch

Patch and bzip2 sources are shared with the Android library. The CLI remains generic; ./gradlew verifyFixtures runs the real Taobao pair from Apks/fixtures.json.

CLI 可在命令前加 --timeout-seconds N(1–86400,默认 900)。超时与中断会回收 worker,失败不发布输出。