Timertask atau Handler

104

Katakanlah saya ingin melakukan beberapa tindakan setiap 10 detik dan tidak perlu memperbarui tampilan.

Pertanyaannya adalah: apakah lebih baik (maksud saya lebih efisien dan efektif) menggunakan timer dengan timertask seperti di sini:

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);
}

atau hanya pawang dengan penundaan pasca

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

Saya juga akan berterima kasih jika Anda dapat menjelaskan kapan harus menggunakan pendekatan mana dan mengapa salah satunya lebih efisien daripada yang lain (jika sebenarnya demikian).

keysersoze
sumber
2
Saya telah membaca banyak posting tentang perilaku TimerTasks yang tidak teratur. Saran saya, hindari mereka dan gunakan pendekatan handler / postDelayed.
Konsepsi Suara
1
Saya lebih suka metode Handler-postDelay - Anda memiliki kontrol lebih dan Anda menjadwalkannya dari dalam
mihail
1
Berikut adalah sumber yang bagus untuk Timer vs. Handler
CodyF
TimerTask adalah tugas latar belakang, jadi Anda tidak dapat memperbarui UI. Hanya mengatakan ...
Yousha Aleayoub
1
bekerja untuk saya .. terima kasih
jyotsna

Jawaban:

97

Handlerlebih baik dari TimerTask.

Java TimerTaskdan Android Handlermemungkinkan Anda menjadwalkan tugas yang tertunda dan berulang pada thread latar belakang. Namun, literatur sangat merekomendasikan menggunakan Handlerlebih TimerTaskdi Android (lihat di sini , di sini , di sini , di sini , di sini , dan di sini ).

Beberapa masalah yang dilaporkan dengan TimerTask meliputi:

  • Tidak dapat memperbarui utas UI
  • Kebocoran memori
  • Tidak dapat diandalkan (tidak selalu berfungsi)
  • Tugas yang berjalan lama dapat mengganggu acara terjadwal berikutnya

Contoh

Sumber terbaik untuk semua jenis contoh Android yang pernah saya lihat ada di Codepath . Berikut adalah Handlercontoh dari sana untuk tugas yang berulang.

// 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);

Terkait

Suragch
sumber
6
@Reek Tidak, GC harus mengurusnya. Tapi Anda harus menjaga runnable yang diposting untuk eksekusi yang tertunda. Dalam contoh di atas, runnable yang digunakan adalah instance kelas dalam sehingga menyimpan referensi implisit ke kelas yang memuatnya (yang mungkin berupa aktivitas). Runnable akan tetap berada di antrian pesan looper terkait handler sampai waktu eksekusi berikutnya yang mungkin setelah konteksnya tidak valid dan mungkin membocorkan instance kelas yang memuatnya. Anda dapat menghapus referensi tersebut dengan menggunakan mHandler.removeCallbacks(runnableCode)pada waktu yang tepat (misalnya onStop()untuk suatu kegiatan).
bitbybit
7
Cara terbaik untuk menyajikan referensi !!! (lihat disini, disini, disini, disini, disini, dan disini).
iRavi iVooda
dan bagaimana jika saya ingin menggunakannya di dalam ViewModel? bukankah bertentangan dengan cita-cita tidak memiliki perangkat android di sana?
desgraci
@ Desgraci, saya belum pernah menggunakan ViewModel, tetapi dari dokumentasi saya hanya melihat bahwa ia mengatakan ViewModel tidak boleh mengakses hierarki tampilan atau berisi referensi ke Aktivitas atau Fragmen. Saya tidak melihat apa pun yang melarang memiliki "Android" secara umum.
Suragch
Sampai hari ini referensi tersebut bagi saya sudah usang dan tidak cukup informatif untuk dipertimbangkan. 4 kekurangan yang terdaftar itu hanya nyata jika Anda memprogram kode Anda dengan buruk. TimerTasks masih merupakan pilihan yang sangat baik jika Anda ingin menjalankan sesuatu secara berkala di latar belakang dan pada akhirnya menjalankan sesuatu di UIThread jika kondisi tertentu berlaku.
David
18

Ada beberapa kelemahan menggunakan Timer

Ini hanya membuat utas tunggal untuk menjalankan tugas dan jika tugas terlalu lama untuk dijalankan, tugas lain menderita. Itu tidak menangani pengecualian yang dilemparkan oleh tugas dan utas baru saja dihentikan, yang memengaruhi tugas terjadwal lainnya dan mereka tidak pernah dijalankan

Disalin dari:

TimerTask vs Thread.sleep vs Handler postDelayed - paling akurat untuk memanggil fungsi setiap N milidetik?

Praveena
sumber
6
jadi bagaimana dengan satu tugas? sepertinya Timer lebih baik untuk itu karena Anda tidak memiliki overhead antrian pesan?
Michael
2
Saya kira kita tidak akan pernah tahu
Denny
6

Versi Kotlin dari jawaban yang diterima:

val handler = Handler()

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

handler.post(runnableCode)
sma6871.dll
sumber