自动化工具 给 adb 加上全局的设备锁

williamfzc · 2019年04月10日 · 最后由 williamfzc 回复于 2020年04月23日 · 2540 次阅读

项目地址

目标

首先解释一下为什么会有这个需求:

在全自动化管理中,对于 adb 的依赖程度是非常高的。然而,一般来说我们将设备管理逻辑放在比较高的层级来解决:

  • 应用
    • 具体业务
    • 设备管理
  • adb
  • 设备

但显而易见的,由应用来管控 adb 命令实际上是非常软性的(很可能会因为疏忽而影响到其他设备),并没有硬性隔离设备。软件操作的边界不明显将很容易导致管理的越界与混乱。在 jenkins 构建中官方推荐用 lockable resource 来管理资源而不是流水线中用代码进行管理已经说明了很多问题。

然而在日常开发中,使用场景远不局限于 jenkins。那么,有没有一种更加通用的方案?答案就是lockadb

像 adb 一样操作

在命令行中,直接用 ladb 替代 adb 。

lockadb 是 adb 的超集,保留了所有的 adb 功能。理论上所有 adb 支持的功能都可以无缝切换到 ladb。

防冲突机制

lockadb 最关键的特性就是从 adb 层面避免了设备操作冲突。

连入一个设备123456F,我们先让该设备忙碌 20 秒:

ladb -s 123456F shell sleep 20

这样做之后,该设备将被标记为 BUSY 状态。此时你如果想操作它是被禁止的:

ladb -s 123456F shell echo hello

Traceback (most recent call last):
  File "C:\Python37\Scripts\ladb-script.py", line 11, in <module>
    load_entry_point('lockadb', 'console_scripts', 'ladb')()
  File "f:\lockadb\lockadb\client.py", line 106, in main
    LockAdbRunner.run(command)
  File "f:\lockadb\lockadb\client.py", line 95, in run
    with lock_device(device_id):
  File "c:\python37\lib\contextlib.py", line 112, in __enter__
    return next(self.gen)
  File "f:\lockadb\lockadb\client.py", line 39, in lock_device
    assert acquire_device(device_id), 'device {} is busy'.format(device_id)
AssertionError: device 123456F is busy

主动锁定

除了自动模式,你也可以手动给设备加锁,更加自由地管理设备。

# 上锁
ladb acquire 123456F
# 解锁
ladb release 123456F

在你上锁之后,除了主动释放设备,该设备将一直保持在 BUSY 状态。

python API

除了命令行的模式,你也可以直接调用 python API 来管理设备。

from lockadb.client import LockAdbRunner, acquire_device, release_device


DEVICE_ID = '123456F'

acquire_result = acquire_device(DEVICE_ID)
print('acquire result is: {}'.format(acquire_result))
LockAdbRunner.run(['devices'])

# ...

release_result = release_device(DEVICE_ID)
print('release result is: {}'.format(release_result))
LockAdbRunner.run(['devices'])

设计

使用 C/S 架构,S 端启动常驻服务器用于设备的管理,通过 API 提供给 C 端使用。

提供两种形式的 CLI 用法:

  • 命令行 CLI
  • python API

Bug 与建议

这个项目是一个个人想法的实践,不一定是最好的解决方案。欢迎交流 :)

共收到 4 条回复 时间 点赞

我建议是如果已经在 work 的手机 在数据库或者文件里面加 1 个状态标记,执行完释放了 adb 才修改回状态。
链接得时候,先遍历手机池子里 符合状态的手机。

陈子昂 回复

😹 对呀 现在确实是这么设计的

至于为什么用服务器而不是文件与数据库,我的理由是设备状态是个时效性比较强的东西,并不是很有必要进行持久化保存。

这块没太明白 ladb 的用处,但是看好像挺好的一个工具
目前遇到这样的一种场景,一个电脑上有多个软件同时操作手机,但是对应的软件都有自己的 adb,然而这几款软件的 adb 版本却不一样,导致了这个软件连上手机,然后去用另一个软件做操作时就杀死已经连接的软件的 adb server,导致总是不能同时使用两款软件,这块有解决的思路吗?

stride83 回复

建议从 PATH 入手让所有软件都只能感知到一个 adb,多 adb 并存都是邪教,adbd 是独占的。
https://stackoverflow.com/a/27256599/10641498

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册