当 Android 对话框回答太快时,代码未执行(竞争条件)

发布于 2024-11-03 05:53:33 字数 407 浏览 4 评论 0原文

在我的 Android 应用程序中,我有一个对话框,其中包含如下代码:

.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int id) {
    dialog.cancel();
    doStuff();
    doMorestuffThatTakesTime();
}
})

我注意到的是,如果我非常快地按下“是”按钮,则 doStuff() 中的代码不会被执行。我想知道dialog.cancel()命令是否与它有关,但即使它移到最后并完全删除,问题仍然存在。

感觉像是某种竞争条件,但问题是什么以及我应该如何解决这个问题?

In my android app, I have a dialog box which has code like this:

.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int id) {
    dialog.cancel();
    doStuff();
    doMorestuffThatTakesTime();
}
})

The thing I noticed is, that if I press the 'Yes' button very quickly, code in the doStuff() doesn't get executed. I wondered if the dialog.cancel() order had anything to do with it, but the problem exists even with it moved to the end and also removed altogether.

It feels like some sort of race condition, but what is the problem and how should I fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美人迟暮 2024-11-10 05:53:33

警告。更多概念验证代码:
您可以尝试在单击时启动一个线程,如下所示:

    builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {               //cancels itself?
            Thread thread= new Thread( new Runnable() {
                public void run() {
                    try{
                    Thread.sleep(3000); //<== mimic time intensive task
                    }
                    catch(Exception e){             
                    }
                    Log.d(TAG,"done");
                    myHandler.sendEmptyMessage(0);
                }
            });
            thread.setDaemon(true);
            thread.start();
            dialog.dismiss();
        }       
    });

并将消息捕获在单个活动处理程序中:

private Handler myHandler= new Handler(){
    @Override
    public void  handleMessage(Message msg){        
        switch(msg.what){
            case 0:
                this.removeMessages(0);
                Log.d(TAG,"gotit");
             break;
            default:
                super.handleMessage(msg);
                break;
        }
    }
};

如果您尝试从新线程触摸 UI,这将不起作用。

Warning. Yet more proof of concept code:
You could try launching a thread in on click as in:

    builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {               //cancels itself?
            Thread thread= new Thread( new Runnable() {
                public void run() {
                    try{
                    Thread.sleep(3000); //<== mimic time intensive task
                    }
                    catch(Exception e){             
                    }
                    Log.d(TAG,"done");
                    myHandler.sendEmptyMessage(0);
                }
            });
            thread.setDaemon(true);
            thread.start();
            dialog.dismiss();
        }       
    });

And trap the message in the single Activity Handler:

private Handler myHandler= new Handler(){
    @Override
    public void  handleMessage(Message msg){        
        switch(msg.what){
            case 0:
                this.removeMessages(0);
                Log.d(TAG,"gotit");
             break;
            default:
                super.handleMessage(msg);
                break;
        }
    }
};

This will NOT work if you try to touch the UI from the new thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文