var img = captureScreen('/sdcard/DCIM/'+ranStr+'.png'); 这个方法直接卡死

搬砖的阿陆
5
· 17 小时前

回答

Hamibot AI
1
· 17 小时前

文档地址 https://docs.hamibot.com/

captureScreen() 是同步阻塞方法,直接卡死通常由以下原因导致:

  1. 未提前调用 requestScreenCapture() 或权限未授予,系统会等待授权弹窗或抛出 SecurityException 导致线程挂起。
  2. 权限请求成功后未等待截图服务初始化(系统需几百毫秒准备),立即调用会阻塞当前线程。
  3. 目标路径不存在、无写入权限或 Android 版本存储策略限制,导致文件 I/O 阻塞。
  4. 在主线程调用且未做异常捕获,阻塞 UI 渲染循环。

标准修复方案如下:

// 文档地址 https://docs.hamibot.com/
// 1. 请求截图权限
if (!requestScreenCapture()) {
    toastLog("请求截图权限失败");
    hamibot.exit();
}
// 2. 等待系统截图服务就绪
sleep(500);

var ranStr = "screen_" + new Date().getTime();
var savePath = "/sdcard/DCIM/" + ranStr + ".png";

// 3. 确保目录存在
files.ensureDir(savePath);

try {
    // 4. 执行截图(同步阻塞,会暂停当前线程直到完成)
    var result = captureScreen(savePath);
    if (result) {
        toastLog("截图已保存: " + savePath);
    } else {
        toastLog("截图保存失败");
    }
} catch (e) {
    toastLog("截图异常: " + e.message);
}

关键注意事项:

  • captureScreen() 必须配合 requestScreenCapture() 使用,且调用前需预留 300~500ms 等待时间。
  • 该方法会阻塞调用它的线程。若需连续截图或避免卡住主界面,请放入 threads.start() 中执行,并在循环内添加 sleep() 控制频率(建议间隔 ≥1000ms)。
  • Android 10+ 对 /sdcard/ 公共目录写入有严格限制。若仍失败,可改用应用私有目录:var savePath = context.getExternalFilesDir(null).getAbsolutePath() + "/" + ranStr + ".png";
  • 两次调用间隔需大于 16ms,否则系统会返回同一张截图缓存。
  • 确保 Hamibot 已授予“存储”权限,否则写入操作会直接阻塞或失败。

按上述结构调整后,卡死问题即可解决。若仍有异常,请提供完整脚本上下文以便进一步排查。

ℹ️ 内容由 AI 生成,可能不准确,请注意核实