本文介绍我如何用 Go 实现一套与 CoffeeScript 版 adbkit 等价且更易维护的 ADB 工具集,覆盖常用 Host/Device 服务、端口映射、抓屏、日志等能力,并提供命令行工具与可复用的传输层库。
- 源项目(CoffeeScript):https://github.com/openstf/adbkit
- 新实现(Go):https://github.com/airhandsome/go-adb-kit
背景与目标
- 原项目使用 CoffeeScript,依赖老旧,现代 Node 环境下安装与调试成本高。
- 目标:用 Go 实现一套同等功能、接口清晰、便于扩展和部署的 ADB 工具与库,提供跨平台 CLI。
总体架构
- 传输层库:protocol/* + transport/*
- 负责 ADB server 请求/响应编解码、连接管理、Host/Device 服务调用。
- 领域服务:services/*
- 将底层传输封装为更高层面 API(如 logcat 结构化输出、package 安装卸载)。
- 命令行工具:cmd/adbkit/main.go
- 使用 cobra 提供 adbkit 命令集,覆盖日常 ADB 操作。
- TCP-USB 桥接:transport/tcpusb/*
- 纯 Go 实现 ADB 端到端包处理,可把 USB 设备映射为本地 TCP 设备。
目录一览:
- protocol/:请求编码、OKAY/FAIL 状态读取、十六进制长度、常量
- transport/:Host/Device 服务封装(shell、sync、reverse、framebuffer、logcat 等)
- services/:面向场景的函数封装(logcat 解析、pubkey 处理等)
- cmd/adbkit/:CLI
协议原理速览
- 核心包:CNXN、AUTH、OPEN、WRTE、OKAY、CLSE、SYNC
- Host 服务:host:version、host:devices、host-serial:<serial>:、host:transport:<serial>
- Device 服务:shell:...、sync:、framebuffer:、reverse:、forward:、log:...
- 抓屏路径:
- framebuffer:返回 52 字节头 + 原始像素流
- screencap:shell:screencap -p 返回 PNG 流
核心实现模块
- protocol/wire.go
- EncodeRequest 负责发送 #### 长度 + payload
- ReadStatus、ReadHexLength 使用 io.ReadFull 保证边界一致
- transport/conn.go
- 统一管理与 ADB server 的连接
- Transport(serial) 处理设备选择,必要时 wait-for-device 重试
- transport/shell.go
- Shell(ctx, serial, args) 打开设备端 shell,并返回 io.ReadCloser 便于流式复制
- transport/sync.go 与 services/sync/*
- 实现 push/pull/stat 等 SYNC 子协议
- transport/forward.go、transport/reverse.go
- 端口映射:forward:... 与 reverse:...,支持 add/list/remove/all
- transport/framebuffer.go 与 transport/screencap.go
- framebuffer 解析 52 字节头,PNG 编码;不可用时自动回退到 screencap -p
- transport/tcpusb/*
- ADB 包结构、校验与 magic、包读写器、代理服务与 socket 状态机
- 流控:A_WRTE 后等待对端 A_OKAY 再继续发送
TCP-USB 桥接(usb-device-to-tcp)
- 目的:在本地监听端口,把 USB 设备映射为 TCP ADB 设备(adb connect 127.0.0.1:PORT)
- 关键点:
- A_AUTH 流程与 adb.exe 对齐:对 SIGNATURE 再发 TOKEN,促使对端发送 RSAPUBLICKEY
- 正确的 magic(cmd) 计算:(cmd ^ 0xffffffff) & 0xffffffff
- A_OPEN/WRTE/OKAY/CLSE 的双向转发与 needAck 流控,避免丢包与阻塞
CLI 设计
- 使用 cobra 提供友好的子命令与参数:
- devices、version、shell、push、pull
- install、uninstall
- forward add/list/remove/remove-all
- reverse add/list/remove/remove-all
- screencap、framebuffer(自动回退)
- logcat(支持结构化 JSON 输出)
- usb-device-to-tcp(桥接服务)
- ADBKIT_DEBUG=1 时输出调试信息,便于排障。
性能与稳定性
- Go 的 io.Copy + io.Pipe 简化了流式管道,开销低
- 尽量避免复用破损连接:服务失败时新建连接重试
- 对长链路(logcat、tcpusb)使用 goroutine + channel 管理生命周期
快速开始
- 编译:
go build -o adbkit.exe ./cmd/adbkit
示例:
-
# 列设备 ./adbkit devices # 执行命令 ./adbkit shell -s getprop # 抓屏(自动回退) ./adbkit framebuffer -s -o fb.png # 端口反向映射 ./adbkit reverse add -s --local tcp:9001 --remote tcp:9000 # TCP-USB 桥接 ./adbkit usb-device-to-tcp -s -p 6174 adb connect 127.0.0.1:6174
结语
本项目以“协议清晰、实现简单、工程可维护”为目标,完整覆盖了 adbkit 的常用能力,并在 Go 生态下提供稳定的 CLI 与库接口。欢迎在实际自动化、测试、抓取、代理等场景中使用,提出反馈或参与扩展。