客户端跨端的另一种尝试:Go mobile

众所周知, flutterGoogle 在 2018 年发布,用于原生跨端(当然 2.0 可以做更多的事情~)框架,基于 Dart 语言开发。很多人都很奇怪,因为在这段时间内,2012年正式发布的 Go 一直是 Google 主推,为什么 flutter 这个开源框架会使用名不见经传的 Dart 作为开发语言呢?是 Go 不能进行跨端开发么?

其实早在2012年, Google 就在 Github 上开源了基于 Go 的跨端开源解决方案 golang/mobile 并且持续维护。但是对于这个已经开源了9年的“老项目”, Google 官方却在 Readme 中仍然标注这个方案仍然是一个实验性的项目。对于这个项目笔者甚是感兴趣,近期便来调研一番。

编译到 Android

对于如何与移动应用集成, golang/mobile 已经提供了2种方式:

  1. all-in,即整个App都使用 golang 构建
  2. SDK,部分代码使用 golang 构建,App可以通过集成 framework 或者 aar 进行

我们先来尝试 all-in 的方式,笔者使用的 macOS 系统,在已经安装好 golang 运行时的基础上,只要执行以下命令就可以在命令行使用 gomobile 了。

$ go get golang.org/x/mobile/cmd/gomobile

由于不需要考虑签名等繁琐事项,我们使用 golang/mobile 构建一个 apk 试试。

官方已经提供了简单的Demo位于 https://golang.org/x/mobile/example 可以直接 git clone 下来,进入 example 目录后,执行以下命令下载依赖。

$ go get -d golang.org/x/mobile/example/basic

随后,使用 gomobile build 直接将示例代码打包成一个 apk

$ gomobile build -target=android golang.org/x/mobile/example/basic

但是执行这一步的时候,终端缺直接报错了。

gomobile: ~/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm /var/folders/09/4vfx52xs0r5_0dl7s5g8qchr0000gn/T/gomobile-work-745714058/lib/armeabi-v7a/libbasic.so: fork/exec ~/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm: no such file or directory

进入 ~/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/ 这个目录看了下确实不存在 arm-linux-androideabi-nm 这个文件。从文件路径来看 gomobile 应该是通过 NDK 的方式进行编译,在参考了相关的ISSUE后,笔者下载了 android-ndk-r12b-linux-x86_64.zip 这个版本的NDK并且将 arm-linux-androideabi-nm 复制到了报错的路径,继续执行 gomobile build 却发现还是报错。

gomobile: ~/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-nm /var/folders/09/4vfx52xs0r5_0dl7s5g8qchr0000gn/T/gomobile-work-553399005/lib/arm64-v8a/libbasic.so: fork/exec ~/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-nm: no such file or directory

原来是缺失另一个CPU架构的可执行文件,在 android-ndk-r12b-linux-x86_64中找到同名文件,直接复制到报错路径后就可以了。但是执行还是报错,提示缺少 i686-linux-android-nm

在经过了反复折腾,查阅了几个小时资料,对比了几个NDK Bundle后,终于发现问题所在。由于笔者使用的系统是 macOS Big Sur 11.2.1 ,Android Studio只有Beta版可以很好的支持这个操作系统。但是 Android Studio 4.2 PreviewSDK Manager 中默认下载的NDK(版本号 23.0.7196353-beta2)居然不是完整版,缺少了很多包括 nmobjcopy 等重要的可执行文件,所以只需要在 SDK Manager 勾选 Show Package Details ,展开 NDK(Side by side) 后选择稳定版 21.4.7075529 安装即可。

image-20210406224426421

安装后,如果你电脑上NDK的环境变量关联了版本,需要记得在 ~/.bash_profile (或者 ~/.zshrc ,看你使用的shell)中修改NDK的版本路径,比如:

export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/21.4.7075529
# 修改后执行 source ~/.bash_profile

再次执行 gomobile build 后便可以在目录中看到已经编译生成了 basic.apk 。 将这个 apk 拖入AVD,运行 Basic 这个App就可以看到官方Demo的效果啦~

image-20210406224838552