Android 10下Go语言网络应用编译运行问题求助
我来帮你一步步搞定这些问题——你遇到的DNS解析错误本质是Go默认的DNS resolver在Android bionic环境下无法正确调用系统DNS服务,而编译报错则是Go与Android NDK工具链的适配问题,结合你的Go 1.14.13和NDK r16b环境,给你以下针对性方案:
一、先搞定DNS解析失败的核心问题
你用GOARM=arm64 GOOS=linux编译的程序能运行,但网络请求时DNS解析失败,是因为Android的DNS服务并非监听在[::1]:53(这是桌面Linux的常规配置),而是由系统服务通过/system/etc/resolv.conf或Android专属机制管理,Go的标准resolver在linux目标下不会适配Android的这种逻辑。
解决思路:强制Go使用基于cgo的DNS resolver,让它调用Android bionic的resolver函数,这样就能正确走系统DNS服务了。但这需要你用Android目标编译并开启cgo,接下来就解决你遇到的编译报错问题。
二、逐个解决Android交叉编译的报错
针对你碰到的三个编译错误,逐一对应解决:
1. 解决找不到android/log.h头文件问题
开启CGO编译Android目标时,Go需要找到Android NDK的头文件和库文件,你需要正确设置环境变量指定NDK路径:
# 替换成你的NDK实际路径 export NDK=/path/to/your/android-ndk-r16b # 指定arm64架构的工具链 export CC=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc export CXX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-g++ # 指定Android API级别(Android 10对应API 29),同时设置头文件路径 export CGO_CFLAGS="-D__ANDROID_API__=29 -I$NDK/sysroot/usr/include -I$NDK/sysroot/usr/include/aarch64-linux-android" # 设置库文件链接路径 export CGO_LDFLAGS="-L$NDK/sysroot/usr/lib/aarch64-linux-android/29 -L$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/lib/gcc/aarch64-linux-android/4.9"
然后执行编译命令:
CGO_ENABLED=1 GOOS=android GOARCH=arm64 go build -o your-app-name
2. 解决_check_for_64_bit_pointer_matching_GoInt数组大小为负的错误
这个错误是Go 1.14与NDK r16b的类型定义不兼容导致的——Go的GoInt在arm64上是64位,但NDK部分头文件的类型定义与之冲突。你需要在CGO_CFLAGS里添加额外宏定义规避:
# 修改后的CGO_CFLAGS,新增两个宏定义 export CGO_CFLAGS="-D__ANDROID_API__=29 -D_GLIBCXX_USE_C99 -DGOARCH_arm64 -I$NDK/sysroot/usr/include -I$NDK/sysroot/usr/include/aarch64-linux-android"
添加-D_GLIBCXX_USE_C99和-DGOARCH_arm64后,就能解决类型匹配问题。
3. 验证编译后程序的运行
编译完成后,把程序推送到Android设备并运行:
adb push your-app-name /data/local/tmp/ adb shell chmod +x /data/local/tmp/your-app-name adb shell /data/local/tmp/your-app-name
此时程序应该能正常进行DNS解析了——因为基于cgo的resolver会调用Android系统的DNS函数,而非Go自身的实现。
三、额外说明:完全无需依赖gomobile
你提到不想用gomobile,这个方案完全不需要它,直接编译成原生可执行文件,和你原来的linux目标编译流程类似,只是适配了Android的工具链和cgo配置。
另外提一句:Go 1.14版本比较老旧,如果你后续升级到Go 1.16+,对Android的支持会更完善,编译流程也会更简单,但基于你当前的环境,上述方案足够解决问题。
内容的提问来源于stack exchange,提问作者adp162

