function showConfigDialog() {

try {
    log("在UI线程中显示配置对话框");
    
    // 在UI线程中构建并显示对话框
    ui.run(function() {
        // 构建对话框
        var dialog = dialogs.build({
            title: "脚本配置",
            view: ui.layout(
                <vertical padding="16">
                    <text textSize="16sp" textStyle="bold" marginBottom="10">基本设置</text>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="调试模式:" width="100" />
                        <switch id="debugSwitch" checked={config.debugMode} />
                    </linear>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="操作延迟:" width="100" />
                        <numberpicker id="delayPicker" minValue="500" maxValue="3000" value={config.waitTime.operation/100} layout_weight="1" />
                        <text text="毫秒" marginLeft="5" />
                    </linear>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="循环间隔:" width="100" />
                        <numberpicker id="loopPicker" minValue="500" maxValue="2000" value={config.waitTime.loopInterval/100} layout_weight="1" />
                        <text text="毫秒" marginLeft="5" />
                    </linear>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="最大重试次数:" width="100" />
                        <numberpicker id="retryPicker" minValue="1" maxValue="10" value={config.waitTime.maxRetry} layout_weight="1" />
                    </linear>
                </vertical>
            ),
            positive: "确定",
            negative: "取消"
        });
        
        // 显示对话框并处理结果
        var result = dialog.show();
        if (result) {
            // 直接更新配置,因为已经在UI线程中
            config.debugMode = ui.debugSwitch.checked();
            config.waitTime.operation = ui.delayPicker.value() * 100;
            config.waitTime.loopInterval = ui.loopPicker.value() * 100;
            config.waitTime.maxRetry = ui.retryPicker.value();
            log("配置已更新");
        }
    });
} catch (e) {
    log("显示配置对话框时出错: " + e.message);
}

} 脚本运行到这个函数后 无法正常构建UI界面 脚本就会卡死 即使在最上层写入“ui”; 也不行

已存档
七月CX · 2 个月前
第 1 条补充
·
2 个月前

按照你说的修改开头添加"ui"; 移除 ui.run, 运行后手机直接黑屏

第 2 条补充
·
2 个月前

// 创建悬浮窗
var floatyWin = floaty.window(
<vertical padding="5" backgroundColor="#33000000" gravity="center">
<horizontal spacing="0">
<button
id="startBtn"
text="开始"
width="60"
height="30"
textSize="12sp"
margin="0"
padding="2"
/>
<button
id="configBtn"
text="配置"
width="60"
height="30"
textSize="12sp"
margin="0"
padding="2"
/>
<button
id="exitBtn"
text="退出"
width="60"
height="30"
textSize="12sp"
margin="0"
padding="2"
/>
</horizontal>
</vertical>
);

// 设置悬浮窗位置
floatyWin.setPosition(device.width - 500, 100);

// 保持悬浮窗不被关闭
setInterval(function() {}, 1000); 这个悬浮窗的显示会造成与ui界面显示的冲突么

回答

Hamibot AI
1
· 2 个月前

这个问题的解决方案是:

  1. 确保在脚本开头已经正确声明了UI模式:
"ui";
  1. 修改对话框构建方式,避免直接在UI线程中阻塞:
// 文档地址 https://docs.hamibot.com/
function showConfigDialog() {
    try {
        log("显示配置对话框");
        
        var dialog = dialogs.build({
            title: "脚本配置",
            view: ui.layout(
                <vertical padding="16">
                    <text textSize="16sp" textStyle="bold" marginBottom="10">基本设置</text>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="调试模式:" width="100" />
                        <switch id="debugSwitch" checked={config.debugMode} />
                    </linear>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="操作延迟:" width="100" />
                        <numberpicker id="delayPicker" minValue="500" maxValue="3000" value={config.waitTime.operation/100} layout_weight="1" />
                        <text text="毫秒" marginLeft="5" />
                    </linear>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="循环间隔:" width="100" />
                        <numberpicker id="loopPicker" minValue="500" maxValue="2000" value={config.waitTime.loopInterval/100} layout_weight="1" />
                        <text text="毫秒" marginLeft="5" />
                    </linear>
                    
                    <linear gravity="center_vertical" marginBottom="10">
                        <text text="最大重试次数:" width="100" />
                        <numberpicker id="retryPicker" minValue="1" maxValue="10" value={config.waitTime.maxRetry} layout_weight="1" />
                    </linear>
                </vertical>
            ),
            positive: "确定",
            negative: "取消"
        }).on("positive", function() {
            config.debugMode = ui.debugSwitch.checked();
            config.waitTime.operation = ui.delayPicker.value() * 100;
            config.waitTime.loopInterval = ui.loopPicker.value() * 100;
            config.waitTime.maxRetry = ui.retryPicker.value();
            log("配置已更新");
        }).show();
        
    } catch (e) {
        log("显示配置对话框时出错: " + e.message);
    }
}
hamibot.exit();

关键修改点:

  1. 移除ui.run()调用,直接在UI线程中执行
  2. 使用事件监听器而不是阻塞等待对话框结果
  3. 确保UI组件使用正确的方式访问

如果问题仍然存在,建议检查:

  1. 确保config对象已正确初始化
  2. 检查是否有其他脚本代码影响UI线程
  3. 确认设备是否支持UI模式

补充回答 1

当UI界面导致黑屏时,通常有以下几种原因和解决方案:

  1. UI线程阻塞问题
"ui";
// 文档地址 https://docs.hamibot.com/
function showConfigDialog() {
    dialogs.build({
        title: "脚本配置",
        positive: "确定", 
        negative: "取消",
        view: ui.inflate(
            <vertical padding="16">
                <text textSize="16sp" textStyle="bold">基本设置</text>
                <switch id="debugSwitch" text="调试模式" checked={config.debugMode}/>
                <text text="操作延迟:(毫秒)"/>
                <seekbar id="delaySlider" min="500" max="3000" progress={config.waitTime.operation}/>
            </vertical>
        )
    }).on("positive", function(){
        config.debugMode = ui.debugSwitch.checked();
        config.waitTime.operation = ui.delaySlider.progress;
        toast("配置已保存");
    }).show();
}
hamibot.exit();

关键改进:

  1. 使用更简单的UI布局(避免复杂控件)

  2. ui.inflate代替ui.layout

  3. 改用seekbar避免numberpicker可能的问题

  4. 其他可能原因和解决方案

如果仍然黑屏,请按此顺序排查:

  1. 检查Android权限:
if(!requestScreenCapture()){
    alert("请授予屏幕截图权限");
    exit();
}
  1. 确保在主线程调用:
"ui";
ui.post(() => {
    showConfigDialog();
});
  1. 最小化代码测试:
"ui";
dialogs.build({
    title:"测试",
    content:"简单对话框测试",
    positive:"确定"
}).show();
  1. 设备兼容性方案:
"ui";
setTimeout(function(){
    showConfigDialog(); 
}, 500);

如果问题依旧存在,可能是:

  1. 系统UI兼容性问题(尝试换个设备)
  2. 内存不足(关闭其他应用)
  3. Hamibot版本问题(更新到最新版)

建议先测试最简单的对话框是否能显示,再逐步添加复杂功能。


补充回答 2

悬浮窗(floaty.window)和普通UI界面("ui"模式)在 Hamibot 中运行时不会产生直接的冲突,但需要注意以下几点:


不会冲突的情况

  1. 悬浮窗独立于UI线程
    • 悬浮窗是通过系统级浮窗实现,而普通UI界面是通过Hamibot的UI线程渲染,两者属于不同的机制。
  2. 可同时存在
    • 你可以同时显示悬浮窗和dialogs.build()"ui"模式的界面。

⚠️ 需要注意的问题

  1. 触摸事件的优先级

    • 悬浮窗的按钮响应可能会被UI界面的弹窗遮挡,此时需要确保悬浮窗的setTouchable(true)(默认已是可触摸状态)。
  2. 线程安全操作UI控件

    • 如果在悬浮窗按钮的回调中修改UI界面的内容(如更改文本框文字),必须用ui.run包裹:
floatyWin.configBtn.click(function() {
    ui.run(() => {
        dialogs.build({ title: "配置" }).show(); // 安全调用UI对话框
    });
});
  1. 悬浮窗位置调整
    • 全屏UI界面(如游戏画面)可能会遮挡悬浮窗,建议用setPosition()调整悬浮窗位置:
floatyWin.setPosition(device.width - 200, 50); // 放在右上角

🛠 推荐代码改进

// 文档地址 https://docs.hamibot.com/
"ui"; // 仍建议声明UI模式(如果脚本有UI需求)

// 创建悬浮窗
var floatyWin = floaty.window(
    <vertical bg="#33000000" gravity="center">
        <horizontal>
            <button id="startBtn" text="开始" w="60" h="30" textSize="12sp"/>
            <button id="configBtn" text="配置" w="60" h="30" textSize="12sp"/>
            <button id="exitBtn" text="退出" w="60" h="30" textSize="12sp"/>
        </horizontal>
    </vertical>
);

// 设置初始位置(避开系统状态栏)
floatyWin.setPosition(device.width - 180, 50);

// 按钮事件
floatyWin.exitBtn.click(() => {
    floatyWin.close();
    hamibot.exit();
});

floatyWin.configBtn.click(() => {
    ui.run(() => {
        dialogs.build({ title: "配置", positive: "确定" }).show();
    });
});

// 保持脚本运行
setInterval(() => {}, 1000);

总结

  • 不冲突:悬浮窗和UI界面可以共存。
  • 注意事项
    1. 避免悬浮窗被遮挡(调整位置)
    2. 在悬浮窗回调中操作UI控件时用ui.run
    3. 确保悬浮窗的setTouchable(true)(默认已开启)

如果仍有问题,可能是设备权限限制(如未开启“悬浮窗权限”),需检查Hamibot的权限设置。

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