讓 Go 代碼跑上移動端

在一些特定的情況下,我們需要爲移動端實現一些功能,如果爲每一個移動端編寫代碼,不僅工作量大,而且很難維護。

我們使用的一個方案是編寫 Go 代碼,然後分別編譯成不同平臺的代碼。Go 語言本身也提供了跨平臺編譯的方式,但是命令很複雜,需要配置很多參數,容易出錯。目前有一些成熟的庫可以直接使用,在這裏使用的是 gomobile 框架。

本文使用的是 Go1.14,Go 語言的安裝不再贅述。

gomobile 安裝

gomobile 可以把 go 代碼編譯成移動端應用或者**移動端 SDK,**本文演示的是編譯成 SDK。

安裝 gomobile:

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

安裝不上的可以設置國內的 Go 代理:

go env -w GOPROXY=https://goproxy.cn,direct

go mobile 支持 Go Modules,所以不需要在 GOPATH 創建項目。創建了一個基於 Go Modules 的 hello 項目,其中只有一個文件 hello.go,具體代碼如下:

package hello
import "fmt"
func Hello(name string) string {
  return fmt.Sprintf("Hello %s!", name)
}

Android 平臺

安裝 Android Studio,下載最新版本就可以。

通過 Android Studio 的 SDK manager 下載 NDK 和 CMake,選中右下角的 Show Package Details 可以下載特定版本。

gomobile 對 NDK 的兼容性不好,我測試了 NDK 22 及以上版本都會失敗,本文使用的 NDK 版本爲 21.4.7075529,CMake 下載最新版本就可以。

然後配置環境變量:

export ANDROID_HOME=~/Library/Android/sdk
export ANDROID_NDK_HOME=~/Library/Android/sdk/ndk/21.4.7075529

然後在 hello 項目的上一級目錄執行以下命令:

# hello 是 go 項目的目錄
$ gomobile bind -target=android hello

把 Go 代碼編譯成 SDK 使用的是 bind 命令。上面命名執行完成後,就會在產生兩個文件:

hello.aar
hello-sources.jar

然後直接把 hello.aar 導入 到 android studio 中使用,就可以像使用普通 Java 包一樣來調用 hello 方法,這一步就不再演示了,調用代碼如下:

import hello.Hello;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // 省略無關代碼
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 在這裏調用 hello 方法
                Snackbar.make(view, Hello.hello("ray"), Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }
}

IOS 平臺

編譯到 IOS 平臺的需要安裝 XCode 和配套的 Command Line Tools,整個流程會比 Android 平臺簡單不少。

同樣在項目的上級目錄執行下面的命令:

# hello 是 go 項目的目錄
$ gomobile bind -target=ios hello

如果出現這個錯誤:

gomobile: -target=ios requires XCode

到 xcode 中配置一下 Command Line Tools:

上面的命令執行成功之後,就會在本地生成一個 Hello.FrameWork 目錄,這個就是 IOS 平臺上的依賴庫。可以直接把整個目錄拷貝到 IOS 的目錄底下,然後添加到項目的依賴中,就可以在代碼中使用了:

struct ContentView: View {
    var body: some View {
        // 在這裏調用 hello 方法
        Text(HelloHello("ray"))
            .padding()
    }
}

小結

到這裏,Go 代碼在 Android 和 IOS 上都跑起來了,這個工具本質上還是對 Go 命令的封裝。後續我會再寫一篇文章來詳細介紹 gomobile 的實現。

文 / Rayjun

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/0fvhDxYXS2zOHIW3WqjNEg