用go语言编写移动端sdk和app开发

window 11

前言

使用go开发sdk在Android,ios中调,这就需要用到gomobile这个工具来完成

文档

https://github.com/golang/go/wiki/Mobile

安装Golang

https://studygolang.com/dl

https://studygolang.com/dl/golang/go1.18.3.windows-amd64.zip

1
2
3
4
5
6
GOPROXY=https://goproxy.cn
GOPATH=c:/gopath # src bin pkg
GOROOT=c:/go
PATH=%GOPATH%/bin;%GOROOT%/bin

go version

安装JDK

下载地址:https://www.oracle.com/java/technologies/downloads/#java8-windows

现在下载jdk需要注册账号,http://bugmenot.com/view/oracle.com 这个网址有提供账号

设置环境变量

JAVA_HOME=<安装目录>

PATH=%JAVA_HOME%\bin

1
java -version

安装Android SDK

Android SDK包下载

1
https://dl.google.com/android/android-sdk_r24.4.1-windows.zip

在安装java sdk后运行SDK Manager.exe

添加系统变量,变量名:ANDROID_HOME,变量值为:SDK安装路径(如下:)

添加Path路径:

1)添加 build-tools\29.0.3 安装路径(在SDK安装目录下)

2)添加 tools安装路径(在SDK安装目录下)

3)添加platform-tools 安装路径(在SDK安装目录下)

安装NDK

方式一

环境变量

1
2
3
4
NDK=C:\android-ndk-r24
PATH=%NDK%
ANDROID_NDK=%NDK%
ANDROID_NDK_HOME=%NDK%

检查是否安装成功

1
2
3
4
5
ndk-build

Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
C:\android-ndk-r24\build\\..\build\core\build-local.mk:151: *** Android NDK: Aborting . Stop.

方式二(使用方式二)

由于您使用的是独立的Android SDK Manager,因此需要使用

关闭 Android SDK Manager

以管理员身份启动命令提示符

cd 安装Android SDK Manager的路径 \tools\bin

sdkmanager ndk-bundle

接受许可协议

等待很长时间.安装完成,没有任何进度指示器.

最终报告完成时,启动 Android SDK Manager

其他下查看,您会发现 Ndk捆绑包

gomobile init -ndk ~/Library/Android/sdk/ndk-bundle/

安装gomobile

地址:https://github.com/golang/mobile/

1
2
3
4
5
6
go install golang.org/x/mobile/cmd/gomobile@latest
go install golang.org/x/mobile/cmd/gobind@latest

gomobile init

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

检查是否安装成功(c:/gopath/bin)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
gomobile

Gomobile is a tool for building and running mobile apps written in Go.

To install:

$ go install golang.org/x/mobile/cmd/gomobile@latest
$ gomobile init

At least Go 1.16 is required.
For detailed instructions, see https://golang.org/wiki/Mobile.

Usage:

gomobile command [arguments]

Commands:

bind build a library for Android and iOS
build compile android APK and iOS app
clean remove object files and cached gomobile files
init build OpenAL for Android
install compile android APK and install on device
version print version

Use 'gomobile help [command]' for more information about that command.

gomobile命令

为Android和iOS构建一个库

1
gomobile bind [-target android|ios|iossimulator|macos|maccatalyst] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]

Bind 为导入路径命名的包生成语言绑定,并为命名的目标系统编译一个库。

-target标志采用 android(默认)或一个或多个以逗号分隔的 Apple 平台(ios、iossimulator、macos、maccatalyst)。

对于 -target android,bind 命令会生成一个 AAR(Android ARchive)文件,该文件将预编译的 Java API 存根类、编译的共享库以及包目录下 /assets 子目录中的所有资产文件存档。默认情况下,输出名为“.aar”。此 AAR 文件通常用于 Android 库项目的二进制分发,并且大多数 Android IDE 都支持 AAR 导入。例如,在 Android Studio (1.2+) 中,可以使用模块导入向导 (File > New > New Module > Import .JAR or .AAR package) 导入 AAR 文件,并将其设置为新依赖项 (File > Project结构 > 依赖项)。这需要“javac”(版本 1.7+)和 Android SDK(API 级别 15 或更高版本)来为 Android 构建库。环境变量 ANDROID_HOME 必须设置为 Android SDK 的路径。使用 -javapkg 标志为生成的类指定 Java 包前缀。

默认情况下,-target=android 为所有支持的指令集(arm、arm64、386、amd64)构建共享库。可以通过使用架构名称指定目标类型来选择指令集的子集。例如,-target=android/arm,android/386。 对于 Apple 目标平台,gomobile 必须在安装了 Xcode 的 OS X 机器上运行。生成的 Objective-C 类型可以使用 -prefix 标志作为前缀。 对于 -target android,-bootclasspath 和 -classpath 标志用于控制引导类路径和 Go 包装器到 Java 类的类路径。

-v 标志提供详细的输出,包括构建的包列表。 构建标志 -a、-n、-x、-gcflags、-ldflags、-tags、-trimpath 和 -work 与构建命令共享。

有关文档,请参阅“help build”。

编译安卓 APK 和 iOS 应用

1
gomobile build [-target android|ios|iossimulator|macos|maccatalyst] [-o output] [-bundleid bundleID] [build flags] [package]

Build 编译并编码由导入路径命名的应用程序。 命名包必须定义一个主函数。 -target 标志采用 android(默认)或一个或多个以逗号分隔的 Apple 平台(ios、iossimulator、macos、maccatalyst)。

对于 -target android,如果在包目录中定义了 AndroidManifest.xml,则会将其添加到 APK 输出中。否则,将生成默认清单。默认情况下,这会为所有支持的指令集(arm、386、amd64、arm64)构建一个"fat" APK。可以通过使用架构名称指定目标类型来选择指令集的子集。例如。-target=android/arm,android/386。

对于 Apple 目标平台,gomobile 必须在安装了 Xcode 的 OS X 机器上运行。

默认情况下,-target ios 将为 ios 和 iossimulator 生成一个 XCFramework。可以指定多个 Apple 目标,为每个切片创建一个“fat”XCFramework。要为所有 supportec 架构(amd64 和 arm64)生成支持 iOS、macOS 和 macCatalyst 的fat XCFramework,请指定 -target ios,macos,maccatalyst。可以通过使用架构名称指定平台来选择指令集的子集。例如。 --target=ios/arm64,maccatalyst/arm64。

如果包目录包含 assets 子目录,则其内容将复制到输出中。

标志 -iosversion 设置要编译的 iOS SDK 的最低版本。默认版本为 13.0。

标志 -androidapi 设置要编译的 Android API 版本。默认值和最小值为 15。

-target ios 需要 -bundleid 标志,并设置捆绑 ID 以与应用程序一起使用。

-o 标志指定输出文件名。如果未指定,则输出文件名取决于构建的包。

-v 标志提供详细的输出,包括构建的包列表。 构建标志 -a、-i、-n、-x、-gcflags、-ldflags、-tags、-trimpath 和 -work 与构建命令共享。

有关文档,请参阅“help build”。

删除目标文件和缓存的 gomobile 文件

1
gomobile clean

Clean 删除 gomobile init 下载的目标文件和缓存的 NDK 文件

为 Android 构建 OpenAL

1
gomobile init [-openal dir]

如果使用 -openal 指定 OpenAL 源目录,则 init 将构建 Android 版本的 OpenAL 以用于 gomobile 构建和 gomobile 安装。

编译安卓APK并安装在设备上

1
gomobile install [-target android] [build flags] [package]

Install 在附加的移动设备上编译并安装由导入路径命名的应用程序。 仅支持 -target android。 “adb”工具必须在 PATH 上。 构建标志 -a、-i、-n、-x、-gcflags、-ldflags、-tags、-trimpath 和 -work 与构建命令共享。有关文档,请参阅“帮助构建”。

打印版本

1
gomobile version

打印 gomobile 二进制文件和工具的版本

库示例

生成库aar

1
2
3
4
5
mkdir go-mobile-demo
cd go-mobile-demo
go mod init go-mobile-demo
mkdir test1 test2
go get golang.org/x/mobile/bind
1
2
3
4
5
├── go.mod
├── test1
│   └── test1.go
└── test2
└── test2.go

go.mod

1
2
3
4
5
6
7
8
9
10
11
module go-mobile-demo

go 1.18

require (
golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
)

test1.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package test1

import "fmt"

const Version = "v0.0.1"

type Test1 struct {
Name string
Age int
}

func (t *Test1) EchoName() string {
return t.Name
}

func (t *Test1) EchoAge() int {
return t.Age
}

func PrintVersion() {
fmt.Println(Version)
}

// 以下方法名是不允许的
//func (t *Test1) GetAge() int {
// return t.Age
//}

//func (t *Test1) SetAge(age int) {
// t.Age = age
//}

test2.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package test2

type Test2 struct {
Name string
Age int
}

func (t *Test2) EchoName() string {
return t.Name
}

func (t *Test2) EchoAge() int {
return t.Age
}

生成android aar

1
2
3
cd go-mobile-demo

gomobile bind -target=android -ldflags=-extldflags=-Wl,-soname,libgojni.so -o demo.aar ./test1 ./test2

生成ios

1
2
3
cd go-mobile-demo

gomobile bind -target=ios -ldflags=-extldflags=-Wl,-soname,libgojni.so -o demo.framework ./test1 ./test2

Android中引用

假设jar和aar都放到module的libs目录下,在module目录下的build.gradle的dependencies中,添加在项目中添加如下:

1
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')

此种方式简单粗暴,但是不允许同时出现同一模块不同编译类型的jar(或aar),

例如,如果libs同时存在test-release.aar和test-debug.aar,他们都是来自同一个module的打包,但是只是编译类型不一样,如果同时存在的话,会编译不过.

1
2
3
4
5
6
7
8
9
10
11
12
apply plugin: 'com.android.application'

android {
...
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])

api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
...
}

Ios中引用

https://github.com/golang/go/wiki/Mobile#building-and-deploying-to-ios-1

android/ios项目

参考

注意版本问题