Android: Kapan saya harus menggunakan Handler () dan kapan saya harus menggunakan Thread?

129

Ketika saya membutuhkan sesuatu untuk berjalan secara tidak sinkron , seperti tugas yang berjalan lama atau logika yang menggunakan jaringan, atau untuk alasan apa pun, Memulai Thread baru dan menjalankannya berfungsi dengan baik. Membuat Handler dan menjalankannya juga berfungsi. Apa bedanya? Kapan saya harus menggunakan masing-masing? Apa keuntungan / alasan untuk menggunakan Handlerdan bukan Thread?

PS. - Demi pertanyaan ini, mari kita abaikan AsyncTask. - Handler().postDelayeduse case jelas bagi saya, demi pertanyaan ini mari kita asumsikan saya perlu tugas untuk memulai segera.

JRun
sumber
Dalam situasi Anda, langsung saja gunakan Thread baru, saran saya berikutnya adalah AsyncTask, tetapi itu bukan yang Anda inginkan dengan jelas. Handler kebanyakan digunakan jika Anda ingin menambahkan penundaan atau jenis penyesuaian lain ke runnable.
kabuto178
1
@ kabuto178 baik, ada manfaat lain dari penangan yang layak disebutkan bahwa Anda melewatkan. Seperti, dapat berinteraksi dengan utas UI dari utas terpisah ..
tony9099

Jawaban:

168

Jika apa pun yang Anda lakukan "berat", Anda harus melakukannya di Thread. Jika Anda tidak memulai secara eksplisit di utasnya sendiri, maka ia akan berjalan pada utas utama (UI) yang mungkin terlihat gelisah atau lambat merespons antarmuka oleh pengguna Anda.

Menariknya ketika Anda menggunakan utas, sering juga berguna untuk menggunakan Handler sebagai sarana komunikasi antara utas yang Anda mulai dan utas utama.

Interaksi Thread / Handler yang khas mungkin terlihat seperti ini:

Handler h = new Handler(){
    @Override
    public void handleMessage(Message msg){
        if(msg.what == 0){
            updateUI();
        }else{
            showErrorDialog();
        }
    }
};

Thread t = new Thread() {
    @Override
    public void run(){
        doSomeWork();
        if(succeed){
            //we can't update the UI from here so we'll signal our handler and it will do it for us.
            h.sendEmptyMessage(0);
        }else{
            h.sendEmptyMessage(1);
        }
    }   
};

Secara umum, yang perlu dibawa pulang adalah Anda harus menggunakan Thread setiap kali Anda melakukan beberapa pekerjaan yang bisa berjalan lama atau sangat intensif (mis. Jaringan apa pun, file IO, aritmatik berat, dll).

FoamyGuy
sumber
Terima kasih atas balasan cepat dan jumlah waktu yang diinvestasikan (dan kecepatan balasan Anda !!)! Jadi, biarkan saya melihat apakah saya mendapatkan ini: Handler dirancang untuk memfasilitasi komunikasi non-pemblokiran antara utas pekerja dan utas UI?
JRun
3
@JRun Itu salah satu kegunaan ya. Lihat deskripsi Handler di dokumen java untuk beberapa info hebat tentangnya. Termasuk salah satu kegunaannya (untuk menjadwalkan pesan dan runnables yang akan dieksekusi sebagai titik di masa depan).
FoamyGuy
@FoamyGuy menjelaskan dengan baik!
tony9099
Hai, apakah dijamin updateUI()akan berjalan setelah onCreateView(setelah tampilan baru dimuat)?
Zyoo
1
Kenapa begitu message.what()? Bukankah begitu if(msg == 0){? Terima kasih banyak! :)
Ruchir Baronia
64

Handler dan Thread benar-benar 2 hal yang berbeda.

Thread harus dibuat untuk menjalankan pekerjaan yang sudah berjalan lama.

Handler adalah objek yang sangat nyaman untuk berkomunikasi antara 2 utas (misalnya: utas latar perlu memperbarui UI. Anda dapat menggunakan Handler untuk memposting beberapa Runnable dari utas latar Anda ke utas UI).

Jadi Anda tidak punya pilihan antara Handler atau Thread. Gunakan utas untuk melakukan pekerjaan berat! (Anda dapat menggunakan Handler jika utas latar belakang Anda akan memicu beberapa pekerjaan untuk dikerjakan di utas lain - sebagian besar waktu utas UI)

ben75
sumber
Terima kasih atas balasan cepat dan jumlah waktu yang diinvestasikan (dan kecepatan balasan Anda !!)!
JRun
28

Handlerdan Threadada dua hal yang berbeda, tetapi mereka tidak saling bertentangan. Anda dapat memiliki Handlerdan Threadpada saat yang sama dan sebenarnya masing-masing Handlerharus berjalan dalam Thread.

Untuk lebih jelasnya, Anda mungkin ingin membaca artikel ini .

masukkan deskripsi gambar di sini

pierrotlefou
sumber
19

A Handlerberjalan di sama Thread, a Threadberjalan di utas berbeda.

Gunakan Handler jika Anda perlu menjalankan sesuatu pada utas yang sama , biasanya elemen GUI atau sesuatu seperti itu.

Gunakan Utas jika Anda ingin utas utama bebas melakukan hal-hal lain . Gunakan ini untuk apa pun yang membutuhkan banyak waktu.

PearsonArtPhoto
sumber
6
mengapa saya harus menggunakan handler jika saya ingin menjalankan sesuatu pada utas yang sama? apa tujuan dari metode mHandler.post (...)?
Elias
1
Elias, dalam kasus seperti itu, Anda dapat menggunakan pawang jika Anda ingin menjalankan tugas tertentu setelah waktu tertentu, atau mengulangi tugas setiap jumlah waktu X. Jika Anda tidak ingin menggunakan hal-hal ini, Anda benar. tidak layak menggunakan pawang. Anda bisa melakukan hal-hal GUI di sana dan kemudian, karena Anda berada di utas UI bagaimanapun, karena pawang berjalan pada utas di mana ia dibuat.
tony9099
14

Penangan adalah cara komunikasi terbaik antara latar belakang dan utas UI. Umumnya Handler dikaitkan dengan antrian pesan dari Thread dan mereka digunakan untuk mengirim pesan dan dapat dijalankan ke Pesan.

MENGGUNAKAN:

Utas: Untuk melakukan tugas dalam utas (Latar Belakang) ulir dari utas UI. (membantu untuk membuka blokir utas UI)

Handler Digunakan untuk berkomunikasi antara UI dan utas Latar.

Lihat artikel ini

Saubhagya Ranjan Das
sumber
4

Jika Anda perlu memperbarui antarmuka pengguna dari Utas baru, Anda harus menyinkronkan dengan utas antarmuka pengguna.

Anda dapat menggunakan kelas android.os.Handler atau kelas AsyncTasks untuk ini.

Kelas Handler dapat memperbarui antarmuka pengguna. Handler menyediakan metode untuk menerima instance dari kelas Message atau Runnable.

Anda dapat memposting pesan melalui metode sendMessage (Pesan pesan) atau melalui metode sendEmptyMessage ().

... info lebih lanjut di sini tentang utas dll. (termasuk turorial untuk berbagai threading dan mekanisme sinkronisasi serta kapan harus menggunakan apa)

Beachwalker
sumber
Terima kasih telah meluangkan waktu untuk menjawab pertanyaan saya. Saya suka blog Lars Vogel, sangat luas dan mudah diikuti. Terima kasih!
JRun
2

Apa keuntungan / alasan menggunakan Handler dan bukan Thread?

Sebuah Handler memungkinkan Anda untuk mengirim dan proses Pesan dan Runnablebenda yang berhubungan dengan thread ini MessageQueue. Setiap Handlerinstance dikaitkan dengan utas tunggal dan antrian pesan utas itu.

Saat Anda membuat yang baru Handler, ia terikat ke antrian utas / pesan dari utas yang membuatnya - sejak saat itu, ia akan mengirimkan pesan dan runnables ke antrian pesan itu dan menjalankannya saat keluar dari antrian pesan .

Ada dua kegunaan utama untuk Handler:

  1. Untuk menjadwalkan pesan dan Runnables akan dieksekusi sebagai titik di masa depan
  2. Untuk enqueue tindakan yang akan dilakukan pada thread yang berbeda dari Anda sendiri.

Jika Anda menggunakan utas java, Anda harus menangani sesuatu sendiri - menyinkronkan dengan utas utama, membatalkan utas dll.

Utas tunggal ini tidak membuat kumpulan utas kecuali Anda menggunakan ThreadPoolExecutoratau ExecutorServiceAPI.

(Ambil permintaan ini dari komentar Anda pada jawaban Blackbelt)

Mengapa tidak menggunakan Pelaksana? dan bahkan jika saya ingin menggunakan Handler untuk melakukan itu, bagaimana?

Referensi: Artikel Kinerja Utas

Ada beberapa jenis pekerjaan yang dapat direduksi menjadi tugas yang sangat paralel dan terdistribusi. Dengan banyaknya paket kerja yang diciptakan, AsyncTaskdan HandlerThreadini bukan kelas yang sesuai. Sifat single-threaded AsyncTaskakan mengubah semua pekerjaan threadpool menjadi sistem linier. Menggunakan HandlerThreadkelas, di sisi lain, akan membutuhkan programmer untuk secara manual mengelola load balancing antara sekelompok thread.

ThreadPoolExecutor adalah kelas pembantu untuk membuat proses ini lebih mudah. Kelas ini mengelola pembuatan sekelompok utas, menetapkan prioritas mereka, dan mengelola bagaimana pekerjaan didistribusikan di antara utas tersebut. Saat beban kerja bertambah atau berkurang, kelas berputar atau menghancurkan lebih banyak utas untuk menyesuaikan dengan beban kerja.

 BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
 ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

Anda bisa merujuk ke artikel panduan pengembang ini di create-threadpool untuk detail lebih lanjut.

Lihat posting ini untuk penggunaan Handlermenjalankan beberapa instance Runnable. Dalam hal ini, semua Runnabletugas akan berjalan dalam satu utas.

Android: Bersulang di utas

Ravindra babu
sumber
1

Handlerdapat digunakan bersamaan dengan Threaduntuk membuat mekanisme Antri. Anda dapat menggunakan handleruntuk memposting sesuatu di InternetThread Looper

Sabuk hitam
sumber
Terima kasih telah meluangkan waktu untuk menjawab pertanyaan saya. Mengapa tidak menggunakan Pelaksana? dan bahkan jika saya ingin menggunakan Handler untuk melakukan itu, bagaimana?
JRun
pelaksana agak berbeda. Untuk menggunakannya, Anda harus memperpanjang utas dan dalam menjalankannya panggil static.metohd prep.of dari kelas Looper. setelah Anda memanggil loop metode statis, sebuah antrian dibuat dan Anda dapat menggunakan perintah handlerbin untuk meneruskan permintaan dan mendapatkan hasil kembali
Blackbelt