在Android上使用网络

在Android上使用网络,android,go,Android,Go,我一直在尝试在Android 10上运行Go应用程序,但遇到了一个障碍。我很确定我现在知道为什么会遇到这个问题,但不知道如何解决它。首先,简单的事情与交叉编译一起工作。比如说, 主程序包 输入“fmt” func main(){ Println(“你好,安卓!”) } 使用GOARM=arm64 GOOS=linux go-build编译后运行正常 但现在如果我添加一些网络代码: 主程序包 进口( “fmt” “net/http” “io/ioutil” ) func main(){ Prin

我一直在尝试在Android 10上运行Go应用程序,但遇到了一个障碍。我很确定我现在知道为什么会遇到这个问题,但不知道如何解决它。首先,简单的事情与交叉编译一起工作。比如说,

主程序包
输入“fmt”
func main(){
Println(“你好,安卓!”)
}
使用
GOARM=arm64 GOOS=linux go-build编译后运行正常

但现在如果我添加一些网络代码:

主程序包
进口(
“fmt”
“net/http”
“io/ioutil”
)
func main(){
Println(“你好,安卓!”)
客户端:=&http.client{}
resp,err:=client.Get(“https://www.google.com")
如果错误!=零{
fmt.Println(错误)
返回
}
bodyBytes,err:=ioutil.ReadAll(resp.Body)
如果错误!=零{
fmt.Println(错误)
返回
}
fmt.Printf(“%s”,bodyBytes)
}
并以与运行相同的方式编译,但我会得到如下错误:

Get "https://www.google.com": dial tcp: lookup www.google.com on [::1]:53: read udp [::1]:47618->[::1]:53: read: connection refused
起初我以为这是我安卓设备上的一些网络配置,但经过大量的混乱之后,我很确定这与安卓网络“不同”这一事实有关。也许这是一个仿生vs libc的东西(?),但至少有一个人似乎通过使用NDK附带的工具链进行构建而成功解决了这个问题

但是,有人知道如何真正实现这一点吗?

起初,我希望它能像
GOOS=android GOARCH=arm64 go build
一样简单,但在以下方面失败了:

# command-line-arguments
/usr/lib/golang/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-384615804/go.o: Relocations in generic ELF (EM: 183)
<bunch of these>
/usr/bin/ld: /tmp/go-link-384615804/go.o: error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status
我搞砸了很多其他的组合,我得到的最接近的结果是在我的NDK安装中指向编译器。基本上类似于
GOARCH=arm64-GOOS=android CC=$NDKROOT/toolschains/arm-linux-androideabi-4.9/prebuild/linux-x86\u 64/bin/arm-linux-androideabi-gcc CGO\u ENABLED=1 CGO\u CFLAGS=“--sysroot$NDKROOT/sysroot-I$NDKROOT/sysroot/usr/include/arm-linux-androideabi/”go build
。但这失败了,因为:

# runtime/cgo
In file included from _cgo_export.c:4:0:
cgo-gcc-export-header-prolog:25:14: error: size of array '_check_for_64_bit_pointer_matching_GoInt' is negative
在我指向编译器的方式中有一些错误-例如,如果不指定sysroot,我将找不到任何头文件(stdlib.h),即使这样,如果不指定额外的include路径,它也找不到特定于体系结构的include(asm/types.h)。因此,这个错误可能是架构和编译器之间的不匹配,我只是不确定在哪里或如何修复它

如果你读过这些,谢谢!其他一些信息:

  • go版本:1.14.13 linux/amd64
  • NDK版本:r16b

我也看过类似的东西,但这似乎更倾向于构建Android应用程序(如APK),尽管我可能在这里遗漏了一些东西。

找到了答案!好吧,我的具体例子起作用了,但我不确定为什么会起作用。答案基本上来自于,你必须:

  • 构建NDK的独立版本(Python脚本中的注释表示它以一种更方便的方式打包,以便其他工具使用)
  • 使用NDK中的交叉编译器重建Go的标准库
  • 使用NDK交叉编译器构建应用程序
以我为例:

$ $(NDKROOT)/build/tools/make_standalone_toolchain.py --arch arm64 --api 24 --install-dir $(HOME)/ndk_standalone
$ CC=$(HOME)/ndk_standalone/bin/clang CXX=$(HOME)/ndk_standalone/bin/clang GOOS=android GOARCH=arm64 go install std
$ CC=$(HOME)/ndk_standalone/bin/clang CXX=$(HOME)/ndk_standalone/bin/clang GOOS=android GOARCH=arm64 CGO_ENABLED=1 go build
和网络工程


与直接调用编译器相比,我不太清楚为什么(或者如果)clang会产生不同。也许我会继续玩这个。此外,在编译应用程序时,我仍然必须显式启用CGO(但不适用于go std库),否则链接失败。

干得好,在编译
https://github.com/inconshreveable/ngrok
适用于android,谢谢。
$ $(NDKROOT)/build/tools/make_standalone_toolchain.py --arch arm64 --api 24 --install-dir $(HOME)/ndk_standalone
$ CC=$(HOME)/ndk_standalone/bin/clang CXX=$(HOME)/ndk_standalone/bin/clang GOOS=android GOARCH=arm64 go install std
$ CC=$(HOME)/ndk_standalone/bin/clang CXX=$(HOME)/ndk_standalone/bin/clang GOOS=android GOARCH=arm64 CGO_ENABLED=1 go build