【问题标题】:Invoking method in endless loop with delay无限循环中延迟调用方法
【发布时间】:2014-02-01 06:46:23
【问题描述】:

如何在无限循环中调用方法,使其每 200 毫秒调用一次?我的意思是:sendMessage() -> wait(200ms) -> sendMessage -> wait(200ms) 等等,除非用户决定不按下按钮。这里以sendMessage方法为例:

private void sendMessage(String message) {
    if (mCommandService.getState() != CommandService.STATE_CONNECTED) {
        Toast.makeText(this, R.string.title_not_connected, Toast.LENGTH_SHORT).show();
        return;
    }
    if (message.length() > 0) {
        byte[] send = message.getBytes();
        mCommandService.write(send);
        mOutStringBuffer.setLength(0);
        mOutEditText.setText(mOutStringBuffer);
    }
}

我不能使用Thread.sleep(),因为它会冻结 UI。我想handler.postDelayed() 的想法在这里也不可行。或者也许是?我怎样才能做到这一点?无论如何我都无法冻结任何活动...

【问题讨论】:

    标签: java android multithreading


    【解决方案1】:

    你试图实现的显然是一个异步任务。处理程序或计时器应该是您的选择。使用 postDelayed,您需要在每次任务完成后调用该方法,因此您的计时器的 scheduleAtFixedRate 应该是您的选择。

    编辑:

    Timer timer;
    TimerTask task;
    

    和 onCreate

    timer = new Timer();
    task = new Sender();
    
    public startTimer() {
        if(task != null) {
            timer.scheduleAtFixedRate(task, 200);
        }
    }
    public stopTimer() {
        timer.cancel();
    }
    private class Sender extends TimerTask {
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            if (mCommandService.getState() != CommandService.STATE_CONNECTED) {
                Toast.makeText(this, R.string.title_not_connected, Toast.LENGTH_SHORT).show();
                return;
            }
            if (message.length() > 0) {
                byte[] send = message.getBytes();
                mCommandService.write(send);
                mOutStringBuffer.setLength(0);
                mOutEditText.setText(mOutStringBuffer);
            }
        }
    
    }
    

    【讨论】:

    • 您能举个例子吗?或者无论如何请参考我的答案?
    • Timer timer = new Timer(); timer.scheduleAtFixedRate(task, 200); 其中 task 是你的 TimerTask,或者一个简单的线程。
    • 当然,使用Timer,你必须手动控制它,比如timer.cancel();在暂停事件上或在恢复时再次安排。
    • 是不是这个:stackoverflow.com/questions/2161750/… 可以参考我的问题吗?
    • 我编辑了帖子并添加了一些示例代码。但我必须警告一件事。您可能想为此使用 Handler 和 PostDelayed,因为即使您的任务未完成, scheduleAtFixedRate 也会每 200 毫秒调用一次。这可能会导致一些问题。另一方面,PostDelayed 将首先被调用,并在 run() 结束时再次调用它,因此将确保完成。你可能想把你的 settext() 包围在 runOnUIThread(new Runnable(..));因为在您设置文本时您的 UI 线程可能正忙,这可能会导致崩溃。
    【解决方案2】:

    使用另一个线程来运行循环。它不应该在 Event Dispatch Thread 中运行,您可以使用 SwingWorker 对象。

    【讨论】:

    • 我对 Android 还很陌生。现在我不知道你的意思是什么,我猜我要去谷歌。谢谢。
    • EDT 是 UI 运行的线程,如果你把一些代码放在中间运行,它将无法绘制更改,直到执行结束。
    • 所以基本上,如果String message在循环中间发生变化,假设我使用scheduleAtFixedRate,方法sendMessage不会注意到这个变化?
    • 不,我不是这个意思。我的意思是你可以使用 Thread.sleep(),但不能在 EDT 中使用。
    猜你喜欢
    • 2018-09-07
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多