Timertask или обработчик

Скажем, что я хочу выполнить какое-то действие каждые 10 секунд, и это необязательно обновлять представление.

Вопрос: лучше (я имею в виду более эффективный и эффективный) использовать таймер с timertask, как здесь:

final Handler handler = new Handler();

TimerTask timertask = new TimerTask() {
    @Override
    public void run() {
        handler.post(new Runnable() {
            public void run() {
               <some task>
            }
        });
    }
};
timer = new Timer();
timer.schedule(timertask, 0, 15000);
}

или просто обработчик с postdelayed

final Handler handler = new Handler(); 
final Runnable r = new Runnable()
{
    public void run() 
    {
        <some task>
    }
};
handler.postDelayed(r, 15000);

Также я был бы признателен, если бы вы могли объяснить, когда использовать какой подход и почему один из них более эффективен, чем другой (если это действительно так).

Ответ 1

Handler лучше, чем TimerTask.

Java TimerTask и Android Handler позволяют вам планировать отложенные и повторяющиеся задачи по фоновым потокам. Тем не менее, литература в подавляющем большинстве рекомендует использовать Handler over TimerTask в Android (см. здесь, здесь, здесь, здесь, здесь и здесь).

Некоторые из зарегистрированных проблем с TimerTask включают:

  • Невозможно обновить поток пользовательского интерфейса.
  • Утечка памяти
  • Ненадежный (не всегда работает)
  • Долгосрочные задачи могут помешать следующему запланированному событию

Пример

Лучший источник для всех видов Android-моделей, которые я видел, находится на Codepath. Ниже приведен пример Handler для повторяющейся задачи.

// Create the Handler object (on the main thread by default)
Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnableCode = new Runnable() {
    @Override
    public void run() {
      // Do something here on the main thread
      Log.d("Handlers", "Called on main thread");
      // Repeat this the same runnable code block again another 2 seconds
      handler.postDelayed(runnableCode, 2000);
    }
};
// Start the initial runnable task by posting through the handler
handler.post(runnableCode);

Похожие

Ответ 2

Есть некоторые недостатки использования таймера

Он создает только один поток для выполнения задач и если выполняется задача слишком долго работать, другие задачи страдают. Он не обрабатывает исключения брошенный задачами, и поток просто заканчивается, что влияет на другие запланированные задачи, и они никогда не выполняются

Скопировано из:

TimerTask vs Thread.sleep vs Handler postDelayed - наиболее точно для вызова функции каждые N миллисекунд?

Ответ 3

Котлинская версия принятого ответа:

val handler = Handler()

val runnableCode = object : Runnable {
    override fun run() {
       Log.d("Handlers", "Called on main thread")
       handler.postDelayed(this, 2000)
    }
}

handler.post(runnableCode)