Skip to content

Commit 9b464a7

Browse files
committed
fix: 多设备环境下所有adb命令统一带-s serial + 前端显示分辨率
根本原因: - _device.extra['serial']从未被设置,导致adb命令不带-s参数 - 多设备环境(MuMu 7555 + emulator 5556)下adb命令冲突 - adb截图、点击、输入、force-stop等全部受影响 修复: 1. launch成功后从Appium caps提取deviceUDID保存到_device.extra['serial'] 2. 将所有裸['adb','shell',...]改为使用_adb_args()(自动带-s参数) - launch中的force-stop/am-start - _rebuild_session_and_launch中的6处adb调用 - _recover_u2_session中的kill_uia2 - _is_u2_process_alive中的ps检测 - _dismiss_keyboard中的keyevent 3. _adb_args()优先使用_device.extra['serial'](Appium真实UDID) 4. 前端设备检测加上分辨率+Android版本显示
1 parent c99962a commit 9b464a7

2 files changed

Lines changed: 31 additions & 13 deletions

File tree

extension/src/sidebarProvider.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,13 @@ ${commonRules}`;
10571057
}
10581058
const serial = lines[0].split("\t")[0];
10591059
const model = (await run(`adb -s ${serial} shell getprop ro.product.model`)).trim() || serial;
1060+
const resRaw = (await run(`adb -s ${serial} shell wm size`)).trim();
1061+
const resolution = resRaw.includes(":") ? resRaw.split(":").pop()!.trim() : "";
1062+
const androidVer = (await run(`adb -s ${serial} shell getprop ro.build.version.release`)).trim();
1063+
const infoParts = [model, resolution, androidVer ? `Android ${androidVer}` : ""].filter(Boolean);
10601064
this._postMessage({
10611065
command: "deviceStatusResult",
1062-
data: { connected: true, message: `设备已连接:${model}`, deviceName: model },
1066+
data: { connected: true, message: `${infoParts.join(",")}`, deviceName: model },
10631067
});
10641068
} catch (err: unknown) {
10651069
const message = err instanceof Error ? err.message : String(err);

src/controller/android.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -443,18 +443,21 @@ async def launch(self) -> None:
443443
# 先杀掉可能残留的 APP 和 U2 进程
444444
# Flutter app 如果已在运行且有活跃动画,XPath 策略会因 waitForIdle 卡死
445445
loop = asyncio.get_event_loop()
446+
adb_pre = ["adb"]
447+
if self._config.device_name:
448+
adb_pre.extend(["-s", self._config.device_name])
446449
if self._config.app_package:
447450
await loop.run_in_executor(
448451
None, lambda: subprocess.run(
449-
["adb", "shell", "am", "force-stop", self._config.app_package],
452+
adb_pre + ["shell", "am", "force-stop", self._config.app_package],
450453
capture_output=True, timeout=5,
451454
)
452455
)
453456
for u2_pkg in ("io.appium.uiautomator2.server",
454457
"io.appium.uiautomator2.server.test"):
455458
await loop.run_in_executor(
456459
None, lambda pkg=u2_pkg: subprocess.run(
457-
["adb", "shell", "am", "force-stop", pkg],
460+
adb_pre + ["shell", "am", "force-stop", pkg],
458461
capture_output=True, timeout=5,
459462
)
460463
)
@@ -483,6 +486,12 @@ async def launch(self) -> None:
483486
self._device.screen_width = int(parts[0])
484487
self._device.screen_height = int(parts[1])
485488
self._device.is_connected = True
489+
# 保存设备序列号到extra,供adb命令(截图/点击/输入等)使用-s参数
490+
device_udid = caps.get("deviceUDID", "") or caps.get("udid", "")
491+
if device_udid:
492+
self._device.extra["serial"] = device_udid
493+
elif self._config.device_name:
494+
self._device.extra["serial"] = self._config.device_name
486495

487496
logger.info("Appium Session 创建成功 | ID={} | 设备={}",
488497
self._session_id[:8], self._device.name)
@@ -518,9 +527,10 @@ async def launch(self) -> None:
518527
component = f"{self._config.app_package}/{self._config.app_activity}"
519528
try:
520529
loop2 = asyncio.get_event_loop()
530+
_adb_fg = self._adb_args()
521531
await loop2.run_in_executor(
522532
None, lambda: subprocess.run(
523-
["adb", "shell", "am", "start", "-n", component],
533+
_adb_fg + ["shell", "am", "start", "-n", component],
524534
capture_output=True, timeout=10,
525535
)
526536
)
@@ -644,9 +654,10 @@ async def _rebuild_session_and_launch(
644654
解决 Flutter app 重启后 UiAutomator2 Server 死锁的问题。
645655
"""
646656
# 1. adb force-stop 杀掉 app
657+
_adb = self._adb_args()
647658
await loop.run_in_executor(
648659
None, lambda: subprocess.run(
649-
["adb", "shell", "am", "force-stop", pkg],
660+
_adb + ["shell", "am", "force-stop", pkg],
650661
capture_output=True, timeout=10,
651662
)
652663
)
@@ -669,12 +680,12 @@ async def _rebuild_session_and_launch(
669680
# 新Session会复用死锁的Server,所以必须手动杀掉
670681
def _kill_uia2():
671682
subprocess.run(
672-
["adb", "shell", "am", "force-stop",
683+
_adb + ["shell", "am", "force-stop",
673684
"io.appium.uiautomator2.server"],
674685
capture_output=True, timeout=5,
675686
)
676687
subprocess.run(
677-
["adb", "shell", "am", "force-stop",
688+
_adb + ["shell", "am", "force-stop",
678689
"io.appium.uiautomator2.server.test"],
679690
capture_output=True, timeout=5,
680691
)
@@ -723,9 +734,10 @@ def _kill_uia2():
723734
logger.warning("设置waitForIdleTimeout失败: {}", e)
724735

725736
# 6. 确保 APP 在前台
737+
_adb2 = self._adb_args()
726738
await loop.run_in_executor(
727739
None, lambda: subprocess.run(
728-
["adb", "shell", "am", "start", "-n", component],
740+
_adb2 + ["shell", "am", "start", "-n", component],
729741
capture_output=True, timeout=10,
730742
)
731743
)
@@ -934,9 +946,10 @@ async def hide_keyboard(self) -> None:
934946
return
935947
loop = asyncio.get_event_loop()
936948
try:
949+
_adb_kb = self._adb_args()
937950
await loop.run_in_executor(
938951
None, lambda: subprocess.run(
939-
["adb", "shell", "input", "keyevent", "111"],
952+
_adb_kb + ["shell", "input", "keyevent", "111"],
940953
capture_output=True, timeout=5,
941954
)
942955
)
@@ -1094,9 +1107,9 @@ def _capture():
10941107
# ── Logcat 日志收集 ──────────────────────────────────
10951108

10961109
def _adb_args(self) -> list[str]:
1097-
"""构建带设备序列号的 adb 命令前缀。"""
1110+
"""构建带设备序列号的 adb 命令前缀。多设备环境必须带 -s。"""
10981111
cmd = ["adb"]
1099-
serial = self._config.device_name
1112+
serial = self._device.extra.get("serial", "") or self._config.device_name
11001113
if serial:
11011114
cmd.extend(["-s", serial])
11021115
return cmd
@@ -1556,7 +1569,7 @@ def _is_u2_process_alive(self) -> bool:
15561569
"""同步检测设备上 UiAutomator2 Server 进程是否存活。"""
15571570
try:
15581571
r = subprocess.run(
1559-
["adb", "shell", "ps", "-A"],
1572+
self._adb_args() + ["shell", "ps", "-A"],
15601573
capture_output=True, text=True, timeout=5,
15611574
)
15621575
return "uiautomator" in r.stdout
@@ -1582,11 +1595,12 @@ async def _recover_u2_session(self) -> None:
15821595
self._session_id = None
15831596

15841597
# 2. 清理残留的 U2 进程
1598+
_adb_r = self._adb_args()
15851599
def _kill_uia2():
15861600
for pkg in ("io.appium.uiautomator2.server",
15871601
"io.appium.uiautomator2.server.test"):
15881602
subprocess.run(
1589-
["adb", "shell", "am", "force-stop", pkg],
1603+
_adb_r + ["shell", "am", "force-stop", pkg],
15901604
capture_output=True, timeout=5,
15911605
)
15921606
await loop.run_in_executor(None, _kill_uia2)

0 commit comments

Comments
 (0)