Android: Apa perbedaan antara Activity.runOnUiThread dan View.post?

Jawaban:

104

Tidak ada perbedaan nyata, kecuali bahwa View.postberguna ketika Anda tidak memiliki akses langsung ke aktivitas.

Dalam kedua kasus, jika tidak pada UI thread, Handler#post(Runnable)akan dipanggil di belakang layar.

Seperti yang disebutkan CommonsWare dalam komentar, ada perbedaan antara keduanya - ketika dipanggil di utas Ui, Activity#runOnUiThreadakan memanggil runmetode secara langsung, sementara View#postakan memposting runnabledi antrian (misalnya memanggil Handler#post)

Poin penting IMO adalah keduanya memiliki tujuan yang sama, dan untuk siapa pun yang menggunakannya, tidak boleh ada perbedaan (dan implementasinya dapat berubah di masa mendatang).

MByD
sumber
70
Satu perbedaan: runOnUiThread()memeriksa utas saat ini dan Runnablesegera mengeksekusinya jika kita kebetulan berada di utas aplikasi utama. post()selalu menempatkan Runnableantrean, tidak peduli utas apa yang dipanggil.
CommonsWare
Terima kasih sekarang saya bisa melihat perbedaan berdasarkan penjelasan Anda dan komentar @CommonsWare.
Alexander Kulyakhtin
4
@Ashwin: "Anda mengatakan runOnUiThread () segera menjalankan Runnable" - tidak, saya tidak melakukannya. Silakan baca kembali komentarnya. Saya berkata " runOnUiThread()periksa utas saat ini dan Runnablesegera jalankan jika kami kebetulan berada di utas aplikasi utama " (penekanan ditambahkan). "Apakah ini berarti bahwa apa pun yang saat ini ada di thread UI diabaikan dan ini diberi prioritas pertama?" - "apa yang pernah saat di thread UI" adalah yang runOnUiThread()panggilan.
CommonsWare
1
@ barn.gumbl: Dalam hal ini, saya melihat sumbernya.
CommonsWare
1
Ada adalah perbedaan. Memposting ke tampilan yang tidak dilampirkan ke jendela tidak akan melakukan apa pun. Meskipun bukan perbedaan yang besar , ini dapat menyebabkan bug halus dan cukup mengganggu untuk dinavigasi jika Anda tidak menyadari perbedaannya.
dcow
23

Perbedaan lain antara Activity.runOnUiThread dan view.post () adalah runnable di view.post () dipanggil setelah tampilan dilampirkan ke jendela.

pareshgoel.dll
sumber
Bagaimana maksud Anda ditampilkan? Menjadi terlihat? Tidak dipanggil sama sekali pada tampilan yang tidak terlihat?
Alexander Kulyakhtin
Memperbaiki ambiguitas Alex.
pareshgoel
5
Ini adalah IMHO perbedaan paling penting. Banyak orang menggunakan view.post () untuk mengeksekusi hal-hal yang perlu dieksekusi SETELAH tampilan dilampirkan.
Sotti
3
Ini tidak benar. Ini tidak pernah benar, tetapi pada titik tertentu JavaDoc untuk View.java salah menyatakan bahwa "View.post hanya berfungsi dari utas lain ketika Tampilan dilampirkan ke jendela". Ini telah diperbaiki pada 15 Oktober 2012, tetapi butuh beberapa saat untuk menembus pikiran para pengembang Android.
Alex Cohn
@ sumber pareshgoel untuk perbedaan ini?
apostleofzion
17

Baik yang diterima untuk kebanyakan situasi dan untuk sebagian besar mereka dipertukarkan, tetapi mereka yang agak berbeda. Perbedaan terbesar tentu saja adalah bahwa yang satu tersedia dari Activitydan yang lainnya dari a View. Ada banyak tumpang tindih di antara keduanya, tetapi terkadang dalam sebuah ActivityAnda tidak akan memiliki akses ke View, dan terkadang dalam sebuah ViewAnda tidak akan memiliki akses ke Activity.

Salah satu kasus tepi yang saya temui View.postsaya sebutkan dalam jawaban untuk pertanyaan SO lain tentangView.post : View.posthanya berfungsi dari utas lain ketika Viewdilampirkan ke jendela. Ini jarang masalah, tapi kadang-kadang dapat menyebabkan Runnableuntuk tidak pernah mengeksekusi, terutama jika Anda memanggil View.postdalam onCreatemetode Anda Activity. Alternatifnya adalah dengan menggunakan Handler.postapa Activity.runOnUiThreaddan tetap View.postdigunakan di bawah selimut.

(diedit untuk akurasi, ditambahkan "dari utas lain")

kabuko
sumber
1
Itu bisa gagal saat tidak terpasang onCreate()juga? Hm, saya berharap untuk memposting ke yang Handlerdisediakan oleh ViewRootdalam kasus itu.
Jens
5
@ Jens Ya, saya telah melihat sumbernya dan View.postharus menambahkan Runnableantrian untuk dieksekusi nanti jika belum terpasang. Saya belum menggali lebih dalam di sumbernya, tetapi dokumen mengatakan: "Metode ini dapat dipanggil dari luar thread UI hanya jika Tampilan ini dilampirkan ke jendela." Jadi saya pikir jika itu di utas saat ini, maka apa yang Anda katakan itu benar, jika tidak maka itu mungkin hanya menelan Runnable. Saya pasti pernah mengalami itu di kode saya.
kabuko
@kabuko Terima kasih jawaban Anda menunjukkan dari poin lain. Bagaimana bisa saya tidak bisa menerima lebih dari 1 jawaban tidak bisa melihat logika di balik itu akan alamat meta forum
Alexander Kulyakhtin
3
Ini tidak benar. Ini tidak pernah benar, tetapi pada titik tertentu JavaDoc untuk View.java salah menyatakan bahwa "View.post hanya berfungsi dari utas lain ketika Tampilan dilampirkan ke jendela". Ini telah diperbaiki pada 15 Oktober 2012, tetapi butuh beberapa saat untuk menembus pikiran para pengembang Android.
Alex Cohn
0

Perbedaan lainnya: postadalah per Tampilan; runOnUiThreadadalah per Aktivitas.

Artinya, Anda dapat (di masa mendatang?) Untuk melakukan view.getQueue/ activity.getQueuedan mendapatkan apa yang Anda inginkan tanpa kode pelacakan atau pemfilteran Anda sendiri.

Pacerier
sumber