从零编译双架构APK:tg-ws-proxy-android 构建指南(cargo-ndk + Gradle 完整流程)
【免费下载链接】tg-ws-proxy-androidAndroid-форк популярного приложения Flowseal - tg-ws-proxy - локальный прокси-сервер MTProto с проксированием CF или без для частичного обхода проблем загрузки Telegram项目地址: https://gitcode.com/gh_mirrors/tg/tg-ws-proxy-android
tg-ws-proxy-android是知名 MTProto 本地代理 tg-ws-proxy 的 Android 移植版:它在手机上启动一个本地 MTProto 代理(默认127.0.0.1:1443),把 Telegram 流量经加密 WebSocket(可走 CloudFlare)转发到数据センター,从而部分解决加载、连接类问题。项目采用Rust 原生引擎 + Kotlin Compose 界面的双层架构:核心逻辑用 Rust 编写,Kotlin 侧通过 JNA 调用编译出的libtgwsproxy.so。
自己动手从零编译,你就能获得支持arm64-v8a(64位)与armeabi-v7a(32位)双架构的 APK,甚至打包出同时兼容两者的 universal 包。整条流程只有两步:cargo-ndk 编译 .so → Gradle 打包 APK。
一、项目结构与构建原理速览 🗺️
编译前先搞清楚每个部分在哪里、干什么:
| 组成部分 | 路径 | 作用 |
|---|---|---|
| Rust 代理引擎 | src/(proxy.rs、ws.rs、cfproxy.rs、crypto.rs、balancer.rs 等) | 本地 MTProto 代理、WS 连接池、CF 转发、加密逻辑 |
| 原生库导出层 | src/lib.rs | 定义 FFI 导出函数(供 JNA 调用)、全局 tokio 运行时 |
| Rust 工程配置 | Cargo.toml | cdylib动态库、release 极致优化(LTO + strip +opt-level = "z") |
| 编译好的原生库 | app/src/main/jniLibs/ | arm64-v8a/、armeabi-v7a/下的libtgwsproxy.so |
| Kotlin 应用层 | app/src/main/java/com/amurcanov/tgwsproxy/ | Compose 界面、前台服务、快捷开关磁贴 |
| 构建脚本 | build_so.bat、build_apk.bat | 一键编译 .so / 一键打包 APK(Windows 版) |
💡 为什么需要两个 .so?因为
arm64-v8a面向 64 位新设备(minSdk 24),armeabi-v7a面向 32 位老设备(minSdk 21)。两者由 Gradle 的 product flavor 分别打入对应 APK。
Rust 侧的发布优化配置值得看一眼,它把体积压到了极致(见 Cargo.toml):
opt-level = "z" # 按体积优化 lto = true # 链接期优化 codegen-units = 1 panic = "abort" strip = true # 去除符号表二、构建环境准备:Rust、cargo-ndk 与 Android NDK
2.1 工具链版本清单 ✅
| 工具 | 版本要求 | 用途 |
|---|---|---|
| Rust + rustup | 1.70+ | 编译 Rust 代理引擎 |
| cargo-ndk | 最新版 | 封装 NDK 交叉编译,一条命令产出 .so |
| Android NDK | 任意较新版本(需含 24、21 级别 sysroot) | 提供 Android 交叉编译工具链 |
| JDK | 17 | Gradle / Android 构建(gradle-wrapper.properties 使用 Gradle 9.6.0) |
| Android SDK | Platform 35(compileSdk = 35) | app/build.gradle.kts 中指定 |
2.2 安装 Rust 交叉编译目标
cargo-ndk 底层靠 rustup 目标 + NDK 工具链工作,先装好两个 Android 目标:
rustup target add aarch64-linux-android armv7-linux-androideabi cargo install cargo-ndk2.3 配置 NDK 路径
- Android Studio 用户:SDK Manager → SDK Tools 勾选NDK (Side by side)安装,然后记住 NDK 安装目录(如
...\sdk\ndk\26.x.xxxxxxx)。 - 命令行用户:安装后需把 NDK 目录设为环境变量
ANDROID_NDK_HOME(旧版为NDK_HOME),cargo-ndk 靠它定位编译器。这是新手最常踩的坑 ⚠️。
Windows 下项目已内置脚本 build_so.bat,只需把第 10 行的SDK_PATH改为你自己的 SDK 路径,它会自动找到 NDK 版本目录、检测/安装 cargo-ndk 并添加目标。
三、cargo-ndk 编译双架构 .so:核心步骤 🛠️
3.1 两条命令编译 arm64 + arm32
build_so.bat 的核心就是两次cargo ndk build --release,输出直接落到app\src\main\jniLibs下:
# [1/2] 64 位:arm64-v8a,API 24 cargo ndk -t arm64-v8a --platform 24 -o app/src/main/jniLibs build --release # [2/2] 32 位:armeabi-v7a,API 21 cargo ndk -t armeabi-v7a --platform 21 -o app/src/main/jniLibs build --release参数速记:
-t:目标 ABI(arm64-v8a/armeabi-v7a)--platform:最低 Android API 级别-o:.so 输出目录(对应 app/src/main/jniLibs/)--release:走 Cargo.toml 中的 release 优化配置
成功后你会看到两个文件:
app/src/main/jniLibs/arm64-v8a/libtgwsproxy.so app/src/main/jniLibs/armeabi-v7a/libtgwsproxy.soLinux / macOS 用户直接执行上面两条命令即可(
-o后路径写成app/src/main/jniLibs),无需 .bat 脚本。
3.2 编译成功标志
终端末尾出现类似输出即成功:
arm64-v8a: OK [xxxxx bytes] armeabi-v7a: OK [xxxxx bytes]仓库中已经内置了一份编译好的 libtgwsproxy.so,如果你只想体验 Gradle 打包环节,可以跳过本节的重新编译。
四、Gradle 打包 release APK:一键产出三个包 📦
4.1 双架构如何映射到 APK flavor
app/build.gradle.kts 用arch维度定义了三个 flavor,与 .so 一一对应:
| Flavor | minSdk | 包含 ABI | 产出 APK |
|---|---|---|---|
arm32 | 21 | armeabi-v7a | app-arm32-release.apk |
arm64 | 24 | arm64-v8a | app-arm64-release.apk |
universal | 21 | 两者都装 | app-universal-release.apk |
同时 app/build.gradle.kts 中显式声明了jniLibs.srcDirs("src/main/jniLibs"),保证上一步的 .so 被正确打进包内。
4.2 执行打包
脚本 build_apk.bat 的流程是:
- 从 app/build.gradle.kts 读取
versionName(当前为1.2.3),拼出v1.2.3-android前缀; - 校验两个 .so 是否齐全(缺失会提示先运行 build_so.bat);
- 执行
gradlew assembleRelease --no-daemon; - 把三个 APK 复制重命名到
app\release\:
app/release/ ├── v1.2.3-android-universal.apk # 双架构合一,分发给所有人最省事 ├── v1.2.3-android-v8a-minsdk24.apk # 仅 64 位 ARM └── v1.2.3-android-v7a-minsdk21.apk # 仅 32 位 ARM没有 Windows 脚本?任何系统下在项目根目录运行:
./gradlew assembleRelease # Linux / macOS gradlew.bat assembleRelease # Windows4.3 签名说明 🔏
release 构建默认开启混淆与资源压缩(isMinifyEnabled = true+ R8 full mode)。签名逻辑在 app/build.gradle.kts:若根目录local.properties里配置了KEYSTORE_FILE、KEYSTORE_PASSWORD、KEY_ALIAS、KEY_PASSWORD,则用你的 keystore 正式签名;未配置时自动降级为 debug 签名,本地安装测试完全没问题,只是不能用于商店上架或覆盖更新。
性能参数方面,gradle.properties 已为构建机做了调优(4G 堆内存、并行任务、构建缓存、configuration cache),一般无需改动。
五、常见问题快速排查 🩺
| 现象 | 原因与对策 |
|---|---|
cargo ndk提示找不到 NDK | 未设置ANDROID_NDK_HOME环境变量,或 NDK 未安装;对照 build_so.bat 手动指定 |
目标平台报错(如target not installed) | 漏装 rustup 目标:rustup target add aarch64-linux-android armv7-linux-androideabi |
build_apk.bat 报.so not found | 先完成第三节(运行 build_so.bat)再打包 APK |
提示WARNING: Keystore not found, using debug signing | 正常现象,只是没有配置正式签名(见 4.3 节) |
| Gradle 下载 JDK 失败 | settings.gradle.kts 使用 foojay-resolver 自动拉取 JDK 17 工具链,确认网络可访问 Gradle 分发源 |
六、完整流程一图流 🚀
┌─ 环境 ─────────────────────────────────────────────┐ │ rustup target add 双目标 → cargo install cargo-ndk │ │ 安装 Android NDK → 设置 ANDROID_NDK_HOME │ └──────────────────────────────────────────────────────┘ ↓ ┌─ 第 1 步:编译原生库 ───────────────────────────────┐ │ cargo ndk -t arm64-v8a --platform 24 build --release │ │ cargo ndk -t armeabi-v7a --platform 21 build --release│ │ 输出 → app/src/main/jniLibs/{arm64-v8a,armeabi-v7a}/libtgwsproxy.so └──────────────────────────────────────────────────────┘ ↓ ┌─ 第 2 步:Gradle 打包 ─────────────────────────────┐ │ gradlew assembleRelease │ │ 输出 → app/release/ 下 3 个 APK(arm32 / arm64 / universal) └──────────────────────────────────────────────────────┘完成后,推荐安装universal 版:一台 APK 通吃 32 位与 64 位设备。装好应用后打开它,阅读内置的「信息」页说明,点击「启动代理」,再点「应用到 Telegram」,双架构编译的成果就能跑起来了 🎉
关键文件速查:build_so.bat(.so 编译脚本)· build_apk.bat(APK 打包脚本)· app/build.gradle.kts(flavor 与签名配置)· Cargo.toml(Rust 依赖与优化配置)
【免费下载链接】tg-ws-proxy-androidAndroid-форк популярного приложения Flowseal - tg-ws-proxy - локальный прокси-сервер MTProto с проксированием CF или без для частичного обхода проблем загрузки Telegram项目地址: https://gitcode.com/gh_mirrors/tg/tg-ws-proxy-android
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考