首先解释一下为什么会有这个需求:
在全自动化管理中,对于 adb 的依赖程度是非常高的。然而,一般来说我们将设备管理逻辑放在比较高的层级来解决:
但显而易见的,由应用来管控 adb 命令实际上是非常软性的(很可能会因为疏忽而影响到其他设备),并没有硬性隔离设备。软件操作的边界不明显将很容易导致管理的越界与混乱。在 jenkins 构建中官方推荐用 lockable resource 来管理资源而不是流水线中用代码进行管理已经说明了很多问题。
然而在日常开发中,使用场景远不局限于 jenkins。那么,有没有一种更加通用的方案?答案就是lockadb。
在命令行中,直接用 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 来管理设备。
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 用法:
这个项目是一个个人想法的实践,不一定是最好的解决方案。欢迎交流 :)