Android emulator命令行无法终止,Mac Shell脚本执行受阻求助
解决Android模拟器启动阻塞Shell脚本的多设备截图自动化方案
嘿,我完全懂你碰到的这个麻烦——启动模拟器的命令卡着不动,脚本没法往下跑后续的截图逻辑,强制终止还没用,只有等模拟器已经在运行时脚本才能正常执行对吧?我之前做多设备自动化测试时也踩过这个坑,给你几个实用的解决思路和完整脚本示例,帮你搞定多设备截图自动化:
核心问题分析
启动Android模拟器的emulator命令默认会占据当前终端的前台进程,并且持续输出日志,导致脚本被阻塞,后续代码根本没机会执行。就算你用Ctrl+C强制终止,有时候模拟器进程还会残留,反而更麻烦。所以我们需要两个关键操作:
- 把模拟器启动命令放到后台运行,并屏蔽不必要的输出
- 等待模拟器完全启动就绪后再执行截图操作(不然截图会失败)
具体解决方案
1. 后台启动模拟器并屏蔽输出
把原来的启动命令改成这样,让它在后台默默运行,不会阻塞脚本:
# 替换成你的AVD名称 emulator -avd YourAVDName > /dev/null 2>&1 &
> /dev/null:把标准输出(模拟器的日志)扔到“黑洞”,不显示在终端2>&1:把错误输出也重定向到和标准输出一样的地方,避免报错信息干扰&:让命令在后台进程中运行,脚本可以继续执行后续代码
2. 等待模拟器完全就绪
光启动模拟器还不够,得等系统完全启动完成(比如桌面加载好)才能截图。可以通过检查Android系统的sys.boot_completed属性来判断,写一个复用的等待函数:
wait_for_emulator() { local emulator_id=$1 echo "等待模拟器 $emulator_id 启动完成..." while true; do # 获取系统启动状态,忽略可能的adb连接错误 boot_status=$(adb -s $emulator_id shell getprop sys.boot_completed 2>/dev/null) # 当返回值为1时,表示系统启动完成 if [[ "$boot_status" == "1" ]]; then sleep 2 # 额外等2秒确保系统稳定 echo "模拟器 $emulator_id 已就绪!" break fi sleep 3 # 每3秒检查一次 done }
3. 多设备自动化完整脚本
下面是一个可以直接复用的多设备截图脚本,它会自动检查AVD是否已经运行,启动未运行的模拟器,等待就绪后执行截图并保存到本地:
#!/bin/bash # 配置:定义要截图的AVD列表 AVDS=("Pixel_5_API_30" "Pixel_7_API_33" "Nexus_6_API_28") # 截图保存目录 SCREENSHOT_DIR="./emulator_screenshots" # 创建保存目录(如果不存在) mkdir -p $SCREENSHOT_DIR # 等待模拟器就绪的函数 wait_for_emulator() { local emulator_id=$1 echo "等待模拟器 $emulator_id 启动完成..." while true; do boot_status=$(adb -s $emulator_id shell getprop sys.boot_completed 2>/dev/null) if [[ "$boot_status" == "1" ]]; then sleep 2 echo "模拟器 $emulator_id 已就绪!" break fi sleep 3 done } # 遍历所有AVD,执行截图流程 for avd in "${AVDS[@]}"; do # 检查当前AVD是否已经在运行 running_emulator_id="" # 遍历所有已连接的模拟器设备,匹配AVD名称 while read emulator_id _; do if [[ "$emulator_id" == emulator* ]]; then avd_name=$(adb -s $emulator_id emu avd name 2>/dev/null) if [[ "$avd_name" == "$avd" ]]; then running_emulator_id=$emulator_id break fi fi done < <(adb devices) if [[ -n "$running_emulator_id" ]]; then echo "AVD $avd 已在运行,跳过启动步骤..." emulator_id=$running_emulator_id else echo "启动AVD $avd..." # 后台启动模拟器,屏蔽所有输出 emulator -avd "$avd" > /dev/null 2>&1 & # 等待设备被adb识别(给模拟器一点启动时间) sleep 10 # 获取刚启动的模拟器ID emulator_id=$(adb devices | grep emulator | head -n1 | awk '{print $1}') fi # 等待模拟器完全就绪 wait_for_emulator "$emulator_id" # 执行截图操作 timestamp=$(date +%Y%m%d_%H%M%S) screenshot_name="screenshot_${avd}_${timestamp}.png" echo "为 $avd 执行截图..." adb -s "$emulator_id" screencap -p /sdcard/$screenshot_name adb -s "$emulator_id" pull /sdcard/$screenshot_name "$SCREENSHOT_DIR/$screenshot_name" # 清理模拟器上的临时截图文件 adb -s "$emulator_id" shell rm /sdcard/$screenshot_name echo "$avd 的截图已保存到:$SCREENSHOT_DIR/$screenshot_name" done echo "所有多设备截图任务已完成!"
注意事项
- 确保
adb和emulator命令在你的系统PATH中,如果找不到,可以用完整路径(比如~/Library/Android/sdk/emulator/emulator和~/Library/Android/sdk/platform-tools/adb) - 第一次启动模拟器可能需要更长时间,你可以根据实际情况调整
sleep的时长 - 如果遇到adb连接问题,可以先执行
adb kill-server再重新启动adb服务
内容的提问来源于stack exchange,提问作者Son Nguyen
相关产品推荐
相关产品推荐

