惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Security Blog
Microsoft Security Blog
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
罗磊的独立博客
腾讯CDC
云风的 BLOG
云风的 BLOG
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
U
Unit 42
I
InfoQ
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
V2EX
美团技术团队
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
F
Fortinet All Blogs
GbyAI
GbyAI
S
SegmentFault 最新的问题

LengYue's Blog

在 Android 中实现 iOS 液态玻璃效果(二:折射与渗透效果) | LengYue's Blog 在 Android 中实现 iOS 液态玻璃效果 | LengYue's Blog Dart 单线程模型的本质 | LengYue's Blog 使用 Rust 开发 Android 底层库,并简化 Java 与 Rust 相互操作 | LengYue's Blog 将 Rust 编译为可在 Android 上使用的二进制文件 | LengYue's Blog Flutter error not found dart html | LengYue's Blog AndroidStudio新版本Logcat | LengYue's Blog Typecho to Hugo | LengYue's Blog GetX Router 设置返回值 | LengYue's Blog Flutter 基础 | Dart 语法 mixin | LengYue's Blog 不使用第三方软件实现Obsidian多平台实时同步 | LengYue's Blog Android 使用字节码 hook 修复第三发 bug | LengYue's Blog 在 Jetpack Compose 中使用输入框(TextField )遇到的一些问题 | LengYue's Blog Android-使用@AutoService实现spi | LengYue's Blog RecyclerView使用优化的ListAdapter | LengYue's Blog ⾃定义布局流程 | LengYue's Blog ViewModel之自定义构造函数 | LengYue's Blog Android Jetpack Compose 超快速上手指南 | LengYue's Blog android 11 [api 30] 适配指南 | LengYue's Blog Android 声明式 UI 框架 Litho 初探 —— Sections API | LengYue's Blog Android 声明式 UI 框架 Litho 初探 —— Layout | LengYue's Blog Android声明式UI框架 Litho 初探 —— MountSpec的使用 | LengYue's Blog Android声明式UI框架 Litho 初探——基础使用 | LengYue's Blog Android声明式UI框架 Litho 初探 ——两种数据类型 | LengYue's Blog
使用 GoMobile 创建 Android、iOS 跨平台 WebSocket Library ...
LengYue · 2023-03-14 · via LengYue's Blog

GoMobile 是 Go 语言的扩展,将 Go 代码编译为可在移动设备上运行的静态库或动态库,可在 iOS 和 Android 平台上使用。本文介绍如何使用 GoMobile 创建 Android 应用并在其中调用 Go 语言 WebSocket。

安装 GoMobile

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

创建 Go WebSocket 库

首先创建一个 Go WebSocket 服务端:

mkdir go-websocket
cd go-websocket
go mod init go-socket
// 使用 gomobile 初始
gomobile init

如果你无法使用 gomobile init 请检查 GOBIN 是否加入环境变量 我们使用在 go 中广泛使用的 gorilla/websocket 来创建 websocket 服务端:

go get github.com/gorilla/websocket

编写 WebSocket 服务端代码:

package socket
import (
	"flag"
	"log"
	"net/http"
	"github.com/gorilla/websocket"
)
var addr = flag.String("addr", "localhost:8080", "http service address")
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
} // use default options
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
	c, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	defer c.Close()
	for {
		mt, message, err := c.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		log.Printf("recv: %s", message)
		err = c.WriteMessage(mt, message)
		if err != nil {
			log.Println("write:", err)
			break
		}
	}
}
func main() {
	flag.Parse()
	log.SetFlags(0)
	http.HandleFunc("/", handleWebSocket)
	log.Fatal(http.ListenAndServe(*addr, nil))
}
func StartServer() {
	flag.Parse()
	log.SetFlags(0)
	http.HandleFunc("/", handleWebSocket)
	log.Fatal(http.ListenAndServe(*addr, nil))
}

上面这段代码我们使用 Gorilla WebSocket 库来处理 WebSocket 连接。当连接建立后,函数将在一个无限循环中等待来自客户端的消息,并将这些消息原封不动地发送回客户端。 我们可以运行 main 方法来测试 WebSocket 服务器是否正常运行。

构建 Go 库

现在,将我们的 Go 代码编译成一个静态库,以便它可以被 Android 应用程序使用:

 gomobile bind -target=android/arm64 -o go-websocket.aar -classpath com.apkdv.websocket 

- o 指定输出文件的名字。
-classpath 指定输出的类包名

创建 Android 应用程序

在 Android Studio 中创建一个新项目。选择 “Empty Activity” 模板。 将刚刚创建的 Go 库导入到 Android 项目中:

  • 将 go-websocket.aar 文件复制到 Android 项目的 libs 文件夹中。如果该文件夹不存在,则需要手动创建。
  • 在 App 的 build.gradle dependencies 下添加: api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
  • 同时我们使用 okHttp 连接我们的 go-websocket 最终我们的 dependencies 如下: 接下来在 MainActivity 中使用 okhttp 连接 websocket 服务:
val request = Request.Builder()
            .url("ws://127.0.0.1:8080")
            .build()
        val client = OkHttpClient.Builder()
            .pingInterval(10, TimeUnit.SECONDS)
            .build()
        webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                super.onOpen(webSocket, response)
                webSocket.send("Hello, server!")
            }
            override fun onMessage(webSocket: WebSocket, text: String) {
                super.onMessage(webSocket, text)
                Log.d(TAG, "Received message: $text")
            }
            override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                super.onMessage(webSocket, bytes)
                Log.d(TAG, "Received message: ${bytes.utf8()}")
            }
            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                super.onFailure(webSocket, t, response)
                Log.d(TAG, "WebSocket connection failed: ${t.message}")
            }
        })

建立连接之后,点击按钮,发送一个每次递增的消息

findViewById<TextView>(R.id.text).setOnClickListener {
            index++
            webSocket.send("index $index")
        }

上面的代码。我们首先用 okhttp 连接 go 床架创建的 websocket 服务端,在连接成功后,点击屏幕上的按钮,会向服务端发送一个消息,服务端收到消息后,会将消息原封不动在发送回客户端。 来看看运行日志:

总结

使用 Go 开发跨平台 Library 需要一下步骤:

  • 安装 GoMobile,并使用 gomobile init 初始化 go 项目
  • 使用 GoMobile 将 go 项目编译常 android、iOS 的支持库
  • 将编译的 aar 导入项目
  • 在 Android 项目中使用 aar 借助 GoMobile 我们能简单方便的将 go 代码在移动端使用,下篇文章,我们将介绍如何将 Rust 集成到移动端,与 go 相比,Rust 有更更多的有点。