问题
这一天我在开发我的跨 Windows、Android 的剪贴板同步工具,我遇到了 .apk 文件过大的问题,于是想找解决方案。查出来我使用 npm run tauri android build 命令时会根据在 src-tauri/gen/android/app/build.gradle.kts 中的描述
1 | android { |
你是否注意到了在 buildTypes 下的一个 packaging 字段 里面藏着两个 x86 架构的字段?
我尝试过把这个删掉,然后再编译打包一遍,结果安装包体积依旧没有减小
Tauri给出的打包办法
Tauri 自己给开发者提供的打包方法并没有写的很清楚具体应该怎么在 apk 的打包上如何填写或修改参数来缩小安装包体积: Tauri 给出的打包办法
具体内容:
Build APKs
The AAB format is the recommended bundle file to upload to Google Play, but it is also possible to generate APKs that can be used for testing or distribution outside the store. To compile APKs for your app you can use the argument:–apk
npm
npm run tauri android build -- --apkArchitecture selection
By default Tauri builds your app for all supported architectures (aarch64, armv7, i686 and x86_64). To only compile for a subset of targets, you can use the argument:–target
npm
npm run tauri android build -- --aab --target aarch64 --target armv7
是不是感觉无从下手?没错,主播也找了大半天文档中没给出任何信息,在网上搜索也没查到有什么人能给出解决方案
解决办法
相信点进这篇文章的你们肯定是为了这一部分内容而来的
首先给出你们结论
直接用下面这一行命令
1 | # 最后面的 armv7 替换陈你想要编译的目标架构 |
关于这个解决办法是怎么来的
这个解决办法找来也是稀奇,我最开始就是直接在 Tauri 的 GitHub 项目 上翻 Discussions 。翻了一圈,我还真的点过最后的答案贴里面看过,但是觉得没什么用就关掉了。
后面不想找了,直接让 ChatGPT 帮我找网上的解决内容。结果 ChatGPT 直接导回这篇帖子:
Is it possible to as Tauri to build only to a specific architecture for android? #10511
我当时试了之后真的有用,从原本的39MB包体积降到了13MB
不要尝试 ChatGPT 给出的第二种方法,那个我试过,无法成功的按照预期分别输出安装包
ChatGPT当时的回答是这样的:
好——给你一套可马上动手的方案,目标是把 APK 里把 x86/x86_64 的本地库去掉,只留下 ARM(armeabi-v7a / arm64-v8a),并把体积降到最小。
我把实操步骤分成 “快速临时方案”(只在一次构建时只编译一个 ABI)和 “工程级长效方案”(修改 Gradle 配置,打包时不再携带 x86),外加几条常见的体积优化建议。下面直接贴命令和可粘贴的配置片段 —— 你按情况选用即可。
一、快速临时方案 —— 只构建单个 Rust 目标(适合快速测试手机)
如果你只是想只为手机的 ARM 架构临时编译,可以在 tauri 命令后面多加一层 -- 把 --target 传给 cargo。社区实测有效的用法是:
- armv7(32-bit):
1 | npm run tauri android build -- -- --target armv7 |
- aarch64(arm64 64-bit):
1 | npm run tauri android build -- -- --target aarch64 |
(这条技巧来源于 tauri 社区讨论,效果是只编译指定的 android 目标,从而避免构建所有 ABI。)(GitHub)
注意:这是“只编译一个目标”的快速办法,适合调试或在手机上试跑,但如果你的最终目的是发布到 Play,建议用下面的工程级方案或者直接生成 AAB(Google Play 会按设备分发)。
二、工程级方案(推荐)—— 在 Gradle 层面只打包 ARM ABI
修改 Android 项目里的 Gradle 配置,明确告诉 Gradle 只 include ARM ABI,并启用按 ABI 拆分 APK(生成每个 ABI 的单独 APK),且不生成 universal APK。
编辑项目里的 src-tauri/gen/android/app/ 下的 build.gradle(Groovy)或 build.gradle.kts(Kotlin DSL),把下面的片段放到 android { ... } 里合适位置:
Groovy(build.gradle)示例:
1 | android { |
Kotlin DSL(build.gradle.kts)示例:
1 | android { |
关于 splits / abi 的用法可参考 Android 官方文档(如何按 ABI 拆分 APK)。(Android Developers)
为什么要在 Gradle 层修改?
即便你只编译了某些 Rust 目标,某些依赖或 build 脚本也可能向 libs/ 或 jniLibs/ 放入多 ABI 的 .so。在 Gradle 层明确指定 abiFilters / splits 可以保证最终打包出的 APK 里只包含你想要的 ABI。
三、发布到 Play 的最佳做法:上传 AAB(App Bundle)
如果你要上 Play,直接生成 AAB(而不是一个包含所有 ABI 的 universal APK),Play 会根据用户设备给出按 ABI 优化后的 APK,用户下载体积更小。Tauri 官方也建议可以用 --aab 来生成 app bundle。(Tauri)
示例:
1 | npm run tauri android build -- --aab |
四、额外体积优化建议(常见“APK 变大”的原因与解决)
确认 native 库是否被正确 strip(去掉 debug 符号)
- Release 构建通常会 strip 符号,但如果 AGP / NDK 版本或配置不对可能没被剥离,导致
.so很大。检查ndkVersion是否指定、以及构建日志里有没有 strip 的步骤。Android 文档讲了原理与如何上传符号文件以便崩溃符号化。(Android Developers, issuetracker.google.com)
- Release 构建通常会 strip 符号,但如果 AGP / NDK 版本或配置不对可能没被剥离,导致
资源与代码压缩
- 在
release中启minifyEnabled true(R8/ProGuard)和shrinkResources true可以去掉未使用的资源 & 代码(前端资源没用到也会占空间)。(Mapbox)
- 在
不要生成 universal APK
- 将
universalApk false(或在发布时只上传 AAB)避免把所有 ABI 的.so打包进一个 APK。
- 将
检查第三方库
- 有些第三方 Android 库会自带所有 ABI 的
.so(包括 x86),需要在 Gradle 里用ndk.abiFilters剔除或用 productFlavors 定向。参考社区讨论。(GitHub, Stack Overflow)
- 有些第三方 Android 库会自带所有 ABI 的
五、如何快速验证 APK 里到底打了哪些架构
构建完成后(例如得到 app-arm64-v8a-release.apk 或 app-release.apk),在本地检查 lib 目录:
1 | unzip -l app-release.apk | grep lib/ |
如果看到 lib/armeabi-v7a/... / lib/arm64-v8a/... 就是这些架构被打包进去了;如果还看到 lib/x86/... / lib/x86_64/... 就说明 x86 仍然被包含,需要回去检查 Gradle 配置或依赖。Android 官方也建议用 APK Analyzer 检查。(Android Developers)
六、常见坑(帮你省时间)
- Tauri 的 Android 构建流程会调用 gradle + cargo,各种 target/ABI 可以在两个层面出问题:Cargo(Rust)层和Gradle(Android)层。要真正把 x86 移除,两边都可能需要调整(上面我给了两边的做法)。
- 如果你使用的是
build.gradle.kts(Kotlin DSL),要用isEnable/isUniversalApk/abiFilters.add(...)之类语法,Groovy 写法与 Kotlin DSL 不同,别把两者混用导致配置无效。关于 tauri 生成的 Android 项目,配置文件通常在src-tauri/gen/android/app/下。(Gitea of NextGraph)
七、把上面做法快速复述(可直接复制粘贴)
- 临时只编译 armv7(测试机):
npm run tauri android build -- -- --target armv7 - 永久在 Gradle 中只打 ARM:把下面片段放到
src-tauri/gen/android/app/build.gradle(.kts)的android {}里(根据你用的 DSL 选一份)——见上面的 Groovy / Kotlin 示例(重复一遍就长,这里就不再重复)。
如果你愿意,我可以:
- 直接给你针对你项目里
src-tauri/gen/android/app的完整build.gradle.kts或build.gradle可替换片段(我会同时给 Groovy & Kotlin 版本,按你当前文件名直接替换即可), - 或者帮你检查一遍你打包后 APK 的
unzip -l输出(你把那段unzip -l的输出粘过来我就能看),并告诉你哪条配置没有生效。
要我先把 可直接粘贴的 Gradle 文件片段 给你吗? (我会同时给 Groovy 与 Kotlin 两版,方便你直接替换)