function autoSerivce() {
  if (auto.service !== null) {
    return;
  }
  auto.waitFor();
}

function launch(appName) {
  if (typeof appName !== "string") {
    return;
  }
  let name;
  if (appName) {
    if (appName.startsWith("com.")) {
      name = appName;
    }
    else {
      name = app.getPackageName(appName);
      if (name == null) {
        return;
      }
    }
    app.launchApp(name);
    util.debuglog(app.getPackageInfo(name));
    return name;
  }
}

function controlClick(selector, retry = 3) {
  while (retry--) {
    if (selector.exists()) {
      break;
    }
    selector.waitFor(1000);
  }
  if (retry < 0) {
    throw new Error("元素未找到");
  }
  let flag = selector.click();
  if (flag) {
    console.log("点击成功");
    return;
  }
  throw new Error("点击失败");
}

function whileClick(selector, number) {
  if (number == 0) {
    return;
  }
  selector = uiselector.className('android.widget.TextView').clickable().text(`剩${number}次`).findOne();
  controlClick(selector);
  whileClick(selector, number - 1);
}

function getControlText(selector) {
  let text = selector.text();
  if (text == '' && selector.exists()) {
    throw new Error("控件无文本或者控件不存在");
  }
  return text;
}

setScreenMetrics(1440, 3200);

const main = () => {
  device.keepScreenDim(3600 * 1000);
  autoSerivce();
  let appName = "com.eg.android.AlipayGphone";
  appName = launch(appName);
  // let i = app.intent({
  //   action: 'VIEW',
  //   packageName: appName,
  //   className: 'com.alipay.mobile.nebulax.xriver.activity.XRiverActivity'
  // });
  // Context.startActivity(i);
  // let uisel = uiselector.className('android.widget.Button').clickable().text('福利').findOne();
  // uiselClick(uisel);
  // whileClick(uisel,);
  // device.cancelKeepingAwake();
}

main();
已存档
9lvuvc6718 · 5 个月前

回答

Hamibot AI
1
· 5 个月前

根据你提供的代码和报错信息“形参后缺少')'”,表面上看是某个函数的参数定义有语法错误,但实际上你的代码中并没有明显的语法问题。这可能是由于某些隐藏字符或代码编辑器的问题导致的误报。

以下是逐步排查和解决问题的方法:


1. 检查是否是隐藏字符导致的问题

有时,脚本文件中可能包含不可见的特殊字符(如 BOM 头或其他编码问题),这些字符可能导致解析器在处理代码时出错。解决方法如下:

  • 将代码复制到一个新的文件中。
  • 使用一个可靠的文本编辑器(如 VS Code、Notepad++ 等)重新保存文件,确保文件编码为 UTF-8(无 BOM)。
  • 再次运行脚本,看看问题是否解决。

2. 逐行注释排查

如果问题仍然存在,可以尝试通过注释掉部分代码来定位具体出错的位置:

  • main 函数中注释掉所有调用的函数,仅保留 device.keepScreenDim(3600 * 1000);autoSerivce();
  • 如果此时脚本可以正常运行,则逐步取消注释其他函数调用,直到找到触发错误的具体代码。

例如:

const main = () => {
  device.keepScreenDim(3600 * 1000);
  autoSerivce();
  // let appName = "com.eg.android.AlipayGphone";
  // appName = launch(appName);
};

3. 检查疑似问题点

虽然从语法上看没有明显错误,但以下几处可能需要特别注意:

(1) whileClick 函数中的递归调用

function whileClick(selector, number) {
  if (number == 0) {
    return;
  }
  selector = uiselector.className('android.widget.TextView').clickable().text(`剩${number}次`).findOne();
  controlClick(selector);
  whileClick(selector, number - 1); // 递归调用
}

这里需要注意:

  • 如果 selector 在递归过程中变为无效值,可能会导致后续调用失败。
  • 你可以尝试将 selector 的赋值移到函数外部,避免重复查找。

修改后的代码:

function whileClick(number) {
  if (number == 0) {
    return;
  }
  let selector = uiselector.className('android.widget.TextView').clickable().text(`剩${number}次`).findOne();
  controlClick(selector);
  whileClick(number - 1); // 递归调用
}

(2) controlClick 函数中的 while 循环

function controlClick(selector, retry = 3) {
  while (retry--) {
    if (selector.exists()) {
      break;
    }
    selector.waitFor(1000);
  }
  if (retry < 0) {
    throw new Error("元素未找到");
  }
  let flag = selector.click();
  if (flag) {
    console.log("点击成功");
    return;
  }
  throw new Error("点击失败");
}

这里的逻辑应该没有问题,但如果你担心 selector 对象的状态变化,可以在每次循环中重新获取 selector

修改后的代码:

function controlClick(selector, retry = 3) {
  while (retry--) {
    selector = selector.selector; // 确保 selector 是最新的
    if (selector.exists()) {
      break;
    }
    selector.waitFor(1000);
  }
  if (retry < 0) {
    throw new Error("元素未找到");
  }
  let flag = selector.click();
  if (flag) {
    console.log("点击成功");
    return;
  }
  throw new Error("点击失败");
}

4. 验证工具或环境版本

如果你确认代码没有语法问题,但仍然报错,可能是运行环境(如 Hamibot 或 Hamibot)的版本问题:

  • 检查你使用的工具版本是否是最新的。
  • 查阅相关工具的官方文档或社区论坛,确认是否有类似问题的报告。

5. 调试信息输出

在关键位置添加调试日志,帮助定位问题。例如:

console.log("执行 autoSerivce 函数");
autoSerivce();

console.log("尝试启动应用");
let appName = "com.eg.android.AlipayGphone";
appName = launch(appName);
console.log("应用启动完成:", appName);

console.log("尝试点击控件");
let selector = uiselector.className('android.widget.Button').clickable().text('福利');
controlClick(selector);

6. **总结

本回答由 AI 生成,内容仅供参考

ℹ️ 本回答由 AI 生成,内容仅供参考
9lvuvc6718 · 5 个月前
function autoSerivce() {
  if (auto.service !== null) {
    return;
  }
  auto.waitFor();
}

function getAppPackageName(appName) {
  if (!appName) {
    throw new Error("appName参数不能为空");
  }
  if (typeof appName !== "string") {
    throw new Error("appName参数必须为字符串");
  }
  let name;
  if (appName.startsWith("com.")) {
    name = appName;
  }
  else {
    name = app.getPackageName(appName);
    if (name == null) {
      throw new Error("应用不存在");
    }
  }
  return name;
}

function launch(appName) {
  let name = getAppPackageName(appName);
  app.launchApp(name);
  util.debuglog(app.getPackageInfo(name));
  return name;
}

function getControlExists(selector) {
  if (selector.exists()) {
    return true;
  }
  return false;
}

function controlClick(selector, retry = 3) {
  if (getControlExists(selector) == false) {
    return;
  }
  while (retry--) {
    if (selector.exists()) {
      break;
    }
    selector.waitFor(1000);
  }
  if (retry < 0) {
    throw new Error("元素未找到");
  }
  let flag = selector.click();
  if (flag) {
    console.log("点击成功");
    return;
  }
  throw new Error("点击失败");
}

function whileClick(selector, number) {
  if (getControlExists(selector) == false) {
    return;
  }
  if (number == 0) {
    return;
  }
  selector = uiselector.className('android.widget.TextView').clickable().text(`剩${number}次`).findOne();
  controlClick(selector);
  whileClick(selector, number - 1);
}

function getControlText(selector) {
  let text = selector.text();
  if (text == '' && selector.exists()) {
    throw new Error("控件无文本或者控件不存在");
  }
  return text;
}

setScreenMetrics(1440, 3200);

const main = () => {
  device.keepScreenDim(3600 * 1000);
  autoSerivce();
  let appName = "com.eg.android.AlipayGphone";
  appName = launch(appName);
  // let i = app.intent({
  //   action: 'VIEW',
  //   packageName: appName,
  //   className: 'com.alipay.mobile.nebulax.xriver.activity.XRiverActivity'
  // });
  // Context.startActivity(i);
  // let uisel = uiselector.className('android.widget.Button').clickable().text('福利').findOne();
  // uiselClick(uisel);
  // whileClick(uisel,);
  // device.cancelKeepingAwake();
}

main();

还是报错:运行的形参后缺少")".(脚本id.js#32)形参后缺少")"
确认hamibot版本为最新

神秘机师
2.27k
· 5 个月前

function controlClick(selector, retry = 3) 不支持默认参数值,把 retry = 3 改掉