Лучший способ периодически выполнять действие [пока приложение запущено] - Обработчик?

Я пытаюсь выполнить действие периодически. Я хочу создать новый экземпляр класса после, скажем, всего 3 секунды. Было бы лучше реализовать это с помощью Handler или Thread? Есть ли более простой способ, который я мог бы попробовать? Я действительно не умею использовать потоки - я хочу учиться, но более важно, чтобы я работал над этим, прежде чем беспокоиться о хорошей практике программирования.

    new Thread(){
        public void run(){
            //makes sure the player still has 3 lives left
            while(game == false){
                uiCallback.sendEmptyMessage(0);
                try {
                    Thread.sleep(2000); // wait two seconds before drawing the next flower
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } //sleep for 2 seconds
            }
        }
    }.start();

Ответ 1

Я делаю что-то подобное в своем приложении для Android; Я обновляю некоторые данные в своем интерфейсе каждые 10 секунд. Есть много способов сделать это, но я решил использовать Handler, потому что это очень просто реализовать:

Thread timer = new Thread() {
    public void run () {
        for (;;) {
            // do stuff in a separate thread
            uiCallback.sendEmptyMessage(0);
            Thread.sleep(3000);    // sleep for 3 seconds
        }
    }
});
timer.start();
...
private Handler uiCallback = new Handler () {
    public void handleMessage (Message msg) {
        // do stuff with UI
    }
};

Как вы знаете, вы не можете запускать периодические функции, подобные этому в потоке пользовательского интерфейса, поскольку он блокирует пользовательский интерфейс. Это создает новый Thread, который отправляет сообщение в пользовательский интерфейс, когда это будет сделано, поэтому вы можете обновить свой пользовательский интерфейс новыми результатами любой вашей периодической функции.

Если вам не нужно обновлять пользовательский интерфейс с результатами этой периодической функции, вы можете просто проигнорировать вторую половину кода моего кода и просто создать новый Thread, как показано. Однако обратите внимание: если вы изменяете переменные, разделяемые этим новым Thread и пользовательским интерфейсом, вы столкнулись с проблемами, если вы не синхронизируете. В общем, потоки не являются областью, где вы хотите игнорировать "хорошие методы программирования", потому что вы получите странные, непредсказуемые ошибки, и вы будете проклинать свою программу.

-tjw

Ответ 2

Самое простое - использовать postDelayed() на View (например, виджет), чтобы запланировать Runnable, который работает, а затем перестроит себя.