每X秒运行一次backgound线程(Android Studio)

时间:2018-09-29 10:37:29

标签: android multithreading concurrency

我有一个代码可以播放5种声音,声音之间的延迟为1秒,我希望这部分代码每5秒执行一次(因此,只要布尔变量为true,它就会连续运行,何时执行)胎面行驶停止-这是错误的-我有一个按钮来启动和停止此执行)。一切正常,但问题是我第一次单击按钮时无法摆脱5秒的延迟,因此,当我第一次单击时,声音仅在5秒后才开始。我如何才能立即开始并且只有在第一次开始延迟之后才开始?

这是按钮onClick代码:

public void clickHandlerStartTempo(final View view) {
    if (!tempoOn) {
        Toast toast = Toast.makeText(getApplicationContext(), "Start Tempo!", Toast
                .LENGTH_SHORT);
        toast.show();
        tempoOn = true;
        final Handler handler = new Handler();
        final int delay = 5000; //milliseconds

        handler.postDelayed(new Runnable() {
            public void run() {
                if (tempoOn) {
                    runCode(view);
                    handler.postDelayed(this, delay);
                }
            }
        }, delay);
    } else {
        Toast toast = Toast.makeText(getApplicationContext(), "Stop Tempo!", Toast
                .LENGTH_SHORT);
        toast.show();
        tempoOn = false;
    }

}

这是runCode方法:

public void runCode(View view) {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            playSound(0);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            for (int i = 0; i < 4; i++) {
                if (tempoOn) {
                    playSound(1);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    return;
                }
            }
        }
    };

    Thread thread = new Thread(runnable);
    Log.i(TAG, "runCode: Thread id = " + thread.getId());
    thread.start();
}

我是android开发的新手,任何帮助将不胜感激。 谢谢。

2 个答案:

答案 0 :(得分:0)

首先,您需要在没有线程的情况下弹奏,然后在4计数后执行扩孔5秒逻辑停止线程。

public void onStartPress(){
    playSound();
    someMethod();
}

public void someMethod(){
    Handler uiHandler = new Handler(Looper.getMainLooper());
    uiHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            playSound();
            someMethod();
        }
    },1000);
}

答案 1 :(得分:0)

不要使用实际的Threads,除非您真的想在Ui线程上做一些事情。大多数时候,您确实希望将事情保留在Ui线程上。

对于简单的重复任务,您可以轻松地重新利用CountDownTimer类的用途。通常具有(几乎)无限的运行时间或Long.MAX_VALUE(2.92亿年)。 onTick拳头在开始后立即发生。

private CountDownTimer mTimer;
private void start() {
    if (mTimer == null) {
        mTimer = new CountDownTimer(Long.MAX_VALUE, 5000) {
            @Override
            public void onTick(long millisUntilFinished) {
                // start a beeping countdown
                new CountDownTimer(5000, 1000) {
                    private int state = 1;
                    @Override
                    public void onTick(long millisUntilFinished) {
                        playSound(state);
                        state = state + 1 % 2;
                    }
                    @Override
                    public void onFinish() {
                        playSound(0);
                    }
                }.start();
            }
            @Override
            public void onFinish() { /* ignore, never happens */ }
        };
        mTimer.start();
    }
}
private void stop() {
    if (mTimer != null) {
        mTimer.cancel();
        mTimer = null;
    }
}