一个关于悬浮窗按钮事件的问题( Fragment ScriptListFragment not attached to a context.)

脚本:

// 检查悬浮窗权限
if (!floaty.checkPermission()) {
    // 没有悬浮窗权限,提示用户并跳转请求
    toast("本脚本需要悬浮窗权限来显示悬浮窗,若已禁止请在随后的界面中允许并重新运行本脚本。");
    floaty.requestPermission();
    exit();
} else {
    toastLog('已有悬浮窗权限');
}

// 获取设备屏幕的宽度和高度
var screenWidth = device.width;
var screenHeight = device.height;

// 计算中心坐标
var centerX = screenWidth / 2;
var centerY = screenHeight / 2;

// 创建悬浮窗口
var w = floaty.window(
    <frame gravity="center">
      <vertical>
        <button id="start" text="开始"/>
        <button id="stop" text="停止"/>
      </vertical>
    </frame>
);

// 设置窗口大小和初始位置
w.setSize(170, 400);
w.setPosition(0, 500);
w.exitOnClose();


// 给停止按钮添加点击事件
w.stop.setOnClickListener(function() {
    // 执行停止操作
    toast('停止操作');
    exit(); // 退出脚本
});

// 给开始按钮添加点击事件
w.start.setOnClickListener(function() {
    // 执行开始操作
    toast('开始操作');
    
    // 进行连续点击,这里是点击30次
    for(let i = 0; i < 30; i++) {
        let rxc1 = centerX + Math.random() * 10 - 5;
        let ryc1 = centerY + Math.random() * 10 - 5;
        let rxc2 = centerX + Math.random() * 10 - 5;
        let ryc2 = centerY + Math.random() * 10 - 5;
        click(rxc1, ryc1);
        click(rxc2, ryc2);
        sleep(500);
    }
});

//保持悬浮窗存在
setInterval(() => {}, 1000);

设备信息:

App version: 6.5.7
App version code: 657
Android build version: V12.5.21.0.R
Android release version: 11
Android SDK version: 30
Android build ID: RP1A.200720.011
Device brand: Redmi
Device manufacturer: Xiaomi
Device name: dandelion
Device model: M2006C3LC
Device product name: dandelion
Device hardware name: mt6762
ABIs: [armeabi-v7a, armeabi]
ABIs (32bit): [armeabi-v7a, armeabi]
ABIs (64bit): []

错误信息:

java.lang.IllegalStateException: Fragment ScriptListFragment{2959361} (c8b3c385-d4c4-4fee-9f76-816591b841dc) not attached to a context.
androidx.fragment.app.Fragment.requireContext(Fragment.java:900)
org.autojs.autojs.ui.main.scripts.ScriptListFragment$explorerView$2.invoke(ScriptListFragment.kt:55)
org.autojs.autojs.ui.main.scripts.ScriptListFragment$explorerView$2.invoke(ScriptListFragment.kt:55)
kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
org.autojs.autojs.ui.main.scripts.ScriptListFragment.getExplorerView(ScriptListFragment.kt:55)
org.autojs.autojs.ui.main.MainActivity$onCreate$1$1$1$permission$1.invoke(MainActivity.kt:91)
org.autojs.autojs.ui.main.MainActivity$onCreate$1$1$1$permission$1.invoke(MainActivity.kt:89)
org.autojs.autojs.ui.main.MainActivityKt$rememberExternalStoragePermissionsState$1.invoke(MainActivity.kt:246)
org.autojs.autojs.ui.main.MainActivityKt$rememberExternalStoragePermissionsState$1.invoke(MainActivity.kt:240)
com.google.accompanist.permissions.MutableMultiplePermissionsStateKt$rememberMutableMultiplePermissionsState$launcher$1.invoke(MutableMultiplePermissionsState.kt:61)
com.google.accompanist.permissions.MutableMultiplePermissionsStateKt$rememberMutableMultiplePermissionsState$launcher$1.invoke(MutableMultiplePermissionsState.kt:57)
androidx.activity.compose.ActivityResultRegistryKt$rememberLauncherForActivityResult$1.invoke$lambda-0(ActivityResultRegistry.kt:106)
androidx.activity.compose.ActivityResultRegistryKt$rememberLauncherForActivityResult$1.$r8$lambda$dCDOHypJPJiF_gC4kcw2C1QNWFU(Unknown Source:0)
androidx.activity.compose.ActivityResultRegistryKt$rememberLauncherForActivityResult$1$$ExternalSyntheticLambda0.onActivityResult(Unknown Source:2)
androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:406)
androidx.activity.ComponentActivity$2$1.run(ComponentActivity.java:188)
android.os.Handler.handleCallback(Handler.java:938)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:236)
android.app.ActivityThread.main(ActivityThread.java:7912)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

运行脚本后,按钮正常出现;点击“”停止“后,正常退出;点击“开始”后,过一段时间autox.js停止运行,出现如上报错(将sleep换成setTimeout还是这样)。

最后由 ZVu2J4DKoQLYd 编辑

AI [GPT-4 (8K)]:

看起来你在尝试使用Auto.js运行一个脚本,但遇到了一些问题。你的脚本在创建和管理一个悬浮窗口,并模拟某些点击事件。然而,在脚本运行过程中发生了一个错误,Fragment ScriptListFragment{2959361} (c8b3c385-d4c4-4fee-9f76-816591b841dc)不再附着于上下文。
java.lang.IllegalStateException 是一个运行时异常,在处理非法状态操作时可能会抛出。在这里,它表示你试图使用一个Fragment,而这个Fragment并没有附加在正确的Context(上下文)上,这通常意味着Fragment已经从Activity中分离或者尚未与Activity关联,但你仍然试图在其中执行某些操作。

可能的解决方案:

确保在Fragment的生命周期中正确地使用Context。确保你没有在Fragment的onDetach()方法之后调用requireContext()方法,因为在onDetach()之后,Fragment不再与其所需的上下文相关联,因此会抛出IllegalStateException。你可以使用getContext()代替requireContext(),以防止此类错误。
确保Fragment已经与Activity关联,才调用requireContext()。你可以在onAttach()方法中设置一个标志,然后检查这个标志,如果Fragment已经附着在上下文上,再进行后续操作。

将点击事件改成赋值之类简短无循环的内容后解决。

// 给停止按钮添加点击事件
w.stop.setOnClickListener(function() {
    // 执行停止操作
    toast('停止操作');
    exit(); // 退出脚本
});

// 给开始按钮添加点击事件
w.start.setOnClickListener(function() {
    // 执行开始操作
    toast('开始操作');
    
    // 进行连续点击,这里是点击30次
    for(let i = 0; i < 30; i++) {
        let rxc1 = centerX + Math.random() * 10 - 5;
        let ryc1 = centerY + Math.random() * 10 - 5;
        let rxc2 = centerX + Math.random() * 10 - 5;
        let ryc2 = centerY + Math.random() * 10 - 5;
        click(rxc1, ryc1);
        click(rxc2, ryc2);
        sleep(500);
    }
});

改为

// 悬浮窗的开始按钮点击事件
w.start.click(()=>{
    // 点击开始,给i赋值1并执行console.log
    i = 1;
    console.log("i的值是" + i);
});

// 悬浮窗的停止按钮点击事件
w.stop.click(()=>{
    // 点击停止,给i,h赋值0并执行console.log
    i = 0;
    h = 0;
    console.log("i的值是" + i);
});

在ui以及悬窗的事件操作函数中,不能直接使用长时间for运行的函数,以及sleep操作,需要把这个代码放到线程中,然后事件去启动这个线程。