多台VirtualBox Android x86设备ADB识别重复问题求助
多Android x86虚拟机ADB多设备识别配置方案
一、VirtualBox虚拟机端口转发配置(核心步骤)
每台虚拟机必须设置唯一的主机端口,才能让ADB识别为不同设备:
- 关闭目标Android x86虚拟机,打开VirtualBox管理器,选中该虚拟机后点击设置 → 网络。
- 选择已启用的网卡(如网卡1),点击高级 → 端口转发。
- 删除默认的ADB转发规则(若存在,通常是主机端口5554、子系统端口5555)。
- 添加新的TCP转发规则:
- 名称:自定义(如ADB_Android1)
- 主机IP:127.0.0.1
- 主机端口:按顺序分配唯一偶数端口,比如第一台用5554,第二台5556,第三台5558...(ADB通过偶数端口标识设备,对应虚拟机内部的5555端口)
- 子系统端口:固定为5555(Android x86默认ADB监听端口)
- 子系统IP:留空或填虚拟机内网IP(如10.0.2.15)
- 重复上述步骤为所有虚拟机配置不重复的主机端口。
二、Android x86虚拟机开启ADB调试
确保虚拟机内ADB服务可被外部连接:
- 启动虚拟机,进入系统后打开设置 → 开发者选项(若未显示,先进入关于手机连续点击版本号启用)。
- 开启USB调试选项。
三、ADB手动连接验证
启动所有虚拟机后,手动建立ADB连接:
adb kill-server # 连接第一台(主机端口5554) adb connect 127.0.0.1:5554 # 连接第二台(主机端口5556) adb connect 127.0.0.1:5556 # 以此类推连接所有虚拟机
执行adb devices,应显示类似如下结果,每台设备有唯一ID:
emulator-5554 device emulator-5556 device emulator-5558 device
四、Python脚本适配修改
针对原脚本的问题,做以下调整以支持多设备控制:
1. 修复ADB命令执行逻辑
原函数将整个命令作为单个参数传入,导致执行失败,需拆分参数:
def run_adb_command(command): cmd_list = ["adb"] + command.split() process = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = process.communicate() return output, error
2. 添加自动连接虚拟机逻辑
虚拟机启动后ADB不会自动识别自定义端口设备,需添加自动连接代码:
def connect_adb_devices(start_port=5554, device_count=20): for i in range(device_count): port = start_port + i * 2 run_adb_command(f"connect 127.0.0.1:{port}") time.sleep(1)
3. 启用多线程控制优化效率
将原循环改为多线程,并行处理多设备的代理配置:
修改后的完整脚本
import subprocess import time import threading def run_adb_command(command): cmd_list = ["adb"] + command.split() process = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = process.communicate() return output, error run_adb_command("kill-server") def start_virtual_devices(): for i in range(1, 21): device_name = "Android " + str(i) subprocess.run(["VBoxManage", "startvm", device_name, "--type", "headless"]) time.sleep(2) def connect_adb_devices(start_port=5554, device_count=20): for i in range(device_count): port = start_port + i * 2 run_adb_command(f"connect 127.0.0.1:{port}") time.sleep(1) def get_connected_devices(): output, error = run_adb_command("devices") devices = [] for line in output.decode().splitlines(): if "\tdevice" in line: device_id = line.split("\t")[0] devices.append(device_id) return devices def set_proxy_and_login(device, proxy, login): # 设置HTTP代理 run_adb_command(f"-s {device} shell settings put global http_proxy {proxy}") # 可选:设置代理认证(部分Android版本支持) # run_adb_command(f"-s {device} shell settings put global proxy_user {login.split(':')[0]}") # run_adb_command(f"-s {device} shell settings put global proxy_pass {login.split(':')[1]}") # 重启WiFi使代理生效 run_adb_command(f"-s {device} shell svc wifi restart") time.sleep(2) print(f"Proxy configured for {device}: {proxy}") # 替换为实际的代理和登录信息 proxies = ["proxy1:8080", "proxy2:8080"] logins = ["user1:pass1", "user2:pass2"] start_virtual_devices() # 等待虚拟机完全启动(时间可根据实际情况调整) time.sleep(30) connect_adb_devices() devices = get_connected_devices() if len(devices) == 0: print("0 devices are connected") exit() print(f"{len(devices)} devices are connected") threads = [] for i in range(len(devices)): device = devices[i] proxy = proxies[i % len(proxies)] login = logins[i % len(logins)] thread = threading.Thread(target=set_proxy_and_login, args=(device, proxy, login)) threads.append(thread) thread.start() print(f"Thread started for {device}") # 等待所有线程执行完成 for thread in threads: thread.join() print("All threads have finished execution")
五、常见问题排查
- 若ADB连接失败,检查主机端口是否被占用(Windows用
netstat -ano | findstr <端口号>,Linux/macOS用lsof -i :<端口号>)。 - 确保虚拟机内ADB服务正在运行,可在虚拟机终端执行
adb start-server。 - 连接失败时尝试重启ADB服务:
adb kill-server && adb start-server后重新连接。
内容的提问来源于stack exchange,提问作者Thomas Decroix
相关产品推荐
相关产品推荐

