var window = null
var taskThreads = null

function init() {
window = floaty.rawWindow(
<vertical w='140dp' h='240dp' padding='8dp' bg='#80000000' id='container'>
<button w='50dp' h='40dp' bg='#03E06D' text='测试' textSize='14sp' textColor='#000000' id='btn1' />
</vertical>
)

// 设置悬浮窗属性
window.setPosition(0, 100)
window.setSize(200, 800)

}
function ceshi(callback) {
console.log('ceshi 执行中...');

setTimeout(() => {
callback(111)
}, 1000)
}

window.btn1.click(() => {
// 按钮1的点击事件
taskThreads = threads.start(function () {
console.log('点击我了');
ceshi()
})
// console.log('点击我了');
// function handle(num){
// console.log('handle 执行中...',num);
// }
// ceshi(handle)
})

main();

setInterval(() => {
if(taskThreads){

if(taskThreads.isAlive()){
  console.log(1111);
  
}

}
}, 1000);
这样的脚本为什么 会出现 hamibot被退出的情况呢 时间不确定 有时候只能挂四五分钟 就被退出了 有时候能挂一个小时

HAMI_1256047566 · 7 天前

回答

Hamibot AI
1
· 7 天前

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

你的脚本出现 Hamibot 被退出(崩溃或自动停止)的情况,主要问题出在 JavaScript 引擎 Rhino 的兼容性问题异步回调中的线程安全问题 上。下面我来详细分析原因并提供修复方案。


❌ 问题分析

1. 箭头函数不被完全支持

你使用了 () => {} 箭头函数:

setTimeout(() => {
  callback(111)
}, 1000)

⚠️ Hamibot 使用的是 Rhino 1.7.15 JavaScript 引擎,不支持 ES6 的箭头函数表达式。虽然部分语法可能能运行,但在某些设备或环境下会导致解析失败、异常退出甚至直接崩溃。

2. 未传入回调函数导致 runtime error

你在点击事件中调用了:

ceshi()

ceshi(callback) 函数需要一个回调参数 callback,而你没有传入。

这会触发:

callback(111) // TypeError: Cannot call method 'call' of undefined

这种错误在非 UI 线程中抛出且未捕获时,可能导致脚本崩溃,严重时会引发 Hamibot 整体退出。

3. 多线程与日志输出冲突(潜在风险)

你在 threads.start() 中执行逻辑,并频繁使用 console.log。如果多个线程同时写入日志,在低性能设备上可能会引起资源争用或缓冲区溢出,增加崩溃概率。


✅ 正确写法(兼容 Rhino 并避免崩溃)

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

var window = null;
var taskThreads = null;

function init() {
  // 创建原始悬浮窗
  window = floaty.rawWindow(
    <vertical w='140dp' h='240dp' padding='8dp' bg='#80000000' id='container'>
      <button w='50dp' h='40dp' bg='#03E06D' text='测试' textSize='14sp' textColor='#000000' id='btn1' />
    </vertical>
  );

  // 设置位置和大小
  window.setPosition(0, 100);
  // 注意:setSize 接收像素值,这里建议用实际 px 或保持 dp 自动转换
  // 若想设置为固定 dp,可使用 device.widthFactor 等换算,否则直接使用数字即可
  window.setSize(-2, -2); // 自适应内容大小,推荐
}

function ceshi(callback) {
  console.log('ceshi 执行中...');
  setTimeout(function () {
    if (typeof callback === 'function') {
      callback(111);
    }
  }, 1000);
}

// 初始化
init();

// 按钮点击监听
window.btn1.click(function () {
  console.log('点击我了');

  // 启动新线程
  taskThreads = threads.start(function () {
    ceshi(function (num) {
      console.log('handle 执行中... ', num);
    });
  });
});

// 定期检查线程状态
setInterval(function () {
  if (taskThreads) {
    if (taskThreads.isAlive()) {
      console.log("当前任务线程正在运行");
    } else {
      console.log("任务线程已结束");
    }
  }
}, 1000);

// 主循环防止脚本退出
hamibot.autoKeepRunning();

🔧 关键修改说明

修改点 原因
() => {} 改为 function () {} 兼容 Rhino 1.7.15,避免语法错误
ceshi() 正确传入回调函数 防止 callback is undefined 错误
添加 typeof callback === 'function' 判断 更安全的调用方式
调用 hamibot.autoKeepRunning() 保证脚本持续运行,防止主流程结束导致退出

💡 建议最佳实践

  1. 永远不要使用 ES6+ 语法
    如:箭头函数、let/const、模板字符串、解构赋值等。

  2. 所有 UI 操作必须通过 ui.run() 更新
    当前例子没涉及动态修改 UI,但如果要改文本、隐藏按钮等,请使用:

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