Android: อะไรคือความแตกต่างระหว่าง Activity.runOnUiThread และ View.post


98

คำตอบ:


105

ไม่มีความแตกต่างที่แท้จริงยกเว้นว่าView.postจะมีประโยชน์เมื่อคุณไม่มีสิทธิ์เข้าถึงกิจกรรมโดยตรง

ในทั้งสองกรณีหากไม่อยู่ในเธรด UI Handler#post(Runnable)จะถูกเรียกอยู่เบื้องหลัง

ตามที่ CommonsWare กล่าวไว้ในความคิดเห็นมีความแตกต่างระหว่างสอง - เมื่อเรียกบน Ui thread Activity#runOnUiThreadจะเรียกใช้runเมธอดโดยตรงในขณะที่View#postจะโพสต์runnableบนคิว (เช่นเรียกHandler#post)

ประเด็นสำคัญ IMO คือทั้งสองมีเป้าหมายเดียวกันและสำหรับใครก็ตามที่ใช้มันไม่ควรมีความแตกต่างกัน (และการนำไปใช้งานอาจมีการเปลี่ยนแปลงในอนาคต)


71
ความแตกต่างอย่างหนึ่ง: runOnUiThread()ตรวจสอบเธรดปัจจุบันและดำเนินการRunnableทันทีว่าเราอยู่บนเธรดแอปพลิเคชันหลักหรือไม่ post()วางRunnableคิวไว้เสมอไม่ว่าจะเรียกใช้เธรดใดก็ตาม
CommonsWare

ขอบคุณตอนนี้ฉันสามารถเห็นความแตกต่างตามคำอธิบายของคุณและความคิดเห็นของ @CommonsWare
Alexander Kulyakhtin

4
@Ashwin: "คุณบอกว่า runOnUiThread () ดำเนินการ Runnable ทันที" - ไม่ฉันไม่ได้ทำ โปรดอ่านความคิดเห็นอีกครั้ง ฉันบอกว่า " runOnUiThread()ตรวจสอบเธรดปัจจุบันและดำเนินการRunnableทันทีหากเราอยู่ในเธรดแอปพลิเคชันหลัก " (เพิ่มการเน้นย้ำ) "หมายความว่าสิ่งที่เคยอยู่ในเธรด UI ถูกละเว้นและสิ่งนี้ให้ความสำคัญเป็นอันดับแรกหรือไม่" - "สิ่งที่เคยอยู่ในเธรด UI" คือการrunOnUiThread()โทร
CommonsWare

1
@ barn.gumbl: ในกรณีนี้ฉันดูที่มา
CommonsWare

1
มีคือความแตกต่าง การโพสต์ไปยังมุมมองที่ไม่ติดกับหน้าต่างจะไม่ทำอะไรเลย แม้ว่าจะไม่แตกต่างกันมากแต่อาจทำให้เกิดข้อบกพร่องเล็กน้อยและค่อนข้างน่ารำคาญในการนำทางหากคุณไม่ทราบถึงความแตกต่างที่มีอยู่
dcow

23

ความแตกต่างอีกประการระหว่าง Activity.runOnUiThread และ view.post () คือ runnable ใน view.post () ถูกเรียกใช้หลังจากที่มุมมองแนบกับหน้าต่าง


คุณหมายถึงแสดงอย่างไร? ปรากฏให้เห็น? ไม่เรียกว่ามองไม่เห็นเลยเหรอ
Alexander Kulyakhtin

แก้ไขความไม่ชัดเจนของ Alex
pareshgoel

5
นี่คือความแตกต่างที่สำคัญที่สุด IMHO ผู้คนจำนวนมากใช้ view.post () เพื่อเรียกใช้งานสิ่งที่ต้องดำเนินการหลังจากที่แนบมุมมอง
Sotti

3
นี่ไม่เป็นความจริง. สิ่งนี้ไม่เคยเป็นจริง แต่ในบางจุด JavaDoc สำหรับ View.java ได้ระบุอย่างไม่ถูกต้องว่า "View.post ทำงานจากเธรดอื่นเมื่อ View แนบกับหน้าต่างเท่านั้น" สิ่งนี้ได้รับการแก้ไขเมื่อวันที่ 15 ตุลาคม 2012 แต่ต้องใช้เวลาสักพักในการเจาะใจนักพัฒนา Android
Alex Cohn

@pareshgoel ที่มาสำหรับความแตกต่างนี้?
apostleofzion

17

ยอมรับได้ในสถานการณ์ส่วนใหญ่และส่วนใหญ่สามารถใช้แทนกันได้ แต่จะแตกต่างกันอย่างละเอียด ความแตกต่างที่ใหญ่ที่สุดแน่นอนคือสิ่งหนึ่งที่มีให้จากActivityและอีกอันหนึ่งจากไฟล์View. มีการทับซ้อนกันมากมาย แต่บางครั้งActivityคุณจะไม่สามารถเข้าถึงไฟล์ a Viewและบางครั้งViewคุณจะไม่สามารถเข้าถึงActivityไฟล์.

หนึ่งในกรณีขอบที่ฉันเคยพบกับView.postฉันได้กล่าวถึงในคำตอบของคำถาม SO อื่นบนView.post : View.postใช้งานได้จากเธรดอื่นเมื่อViewแนบกับหน้าต่างเท่านั้น นี่คือไม่ค่อยมีปัญหา แต่บางครั้งอาจทำให้เกิดRunnableการไม่ดำเนินการโดยเฉพาะอย่างยิ่งถ้าคุณโทรView.postในวิธีการของคุณonCreate Activityอีกทางเลือกหนึ่งคือการใช้Handler.postสิ่งที่เป็นสิ่งที่Activity.runOnUiThreadและView.postใช้ภายใต้ฝาครอบอยู่ดี

(แก้ไขเพื่อความถูกต้องเพิ่ม "จากชุดข้อความอื่น")


1
มันอาจล้มเหลวเมื่อไม่ได้เชื่อมต่อonCreate()ด้วย? อืมฉันคาดหวังว่ามันจะโพสต์ไปยังที่Handlerให้มาViewRootในกรณีนั้น
Jens

5
@Jens ใช่ฉันมองไปที่แหล่งที่มาแล้วและView.postควรเพิ่มในRunnableคิวเพื่อดำเนินการในภายหลังหากยังไม่ได้แนบ ฉันไม่ได้ขุดลึกลงไปในแหล่งที่มามากนัก แต่เอกสารบอกว่า: "วิธีนี้สามารถเรียกใช้จากนอกเธรด UI ได้ก็ต่อเมื่อมุมมองนี้แนบกับหน้าต่างเท่านั้น" ดังนั้นฉันคิดว่าถ้ามันอยู่ในเธรดปัจจุบันสิ่งที่คุณพูดเป็นความจริงถ้าไม่ใช่มันก็อาจจะกลืนกินไฟล์Runnable. ฉันเคยมีสิ่งนั้นเกิดขึ้นในรหัสของฉันอย่างแน่นอน
kabuko

@kabuko ขอบคุณคำตอบของคุณแสดงให้เห็นจากจุดอื่น เป็นอย่างไรฉันไม่สามารถยอมรับคำตอบมากกว่า 1 ข้อไม่เห็นตรรกะที่อยู่เบื้องหลังที่จะตอบคำถามเมตาฟอรัม
Alexander Kulyakhtin

3
นี่ไม่เป็นความจริง. สิ่งนี้ไม่เคยเป็นจริง แต่ในบางจุด JavaDoc สำหรับ View.java ได้ระบุอย่างไม่ถูกต้องว่า "View.post ทำงานจากเธรดอื่นเมื่อ View แนบกับหน้าต่างเท่านั้น" สิ่งนี้ได้รับการแก้ไขเมื่อวันที่ 15 ตุลาคม 2012 แต่ต้องใช้เวลาสักพักในการเจาะใจนักพัฒนา Android
Alex Cohn

0

ความแตกต่างอีกประการหนึ่งpostคือต่อการดู; runOnUiThreadเป็นต่อกิจกรรม

ซึ่งหมายความว่าจะเป็นไปได้ (ในอนาคต?) ที่จะทำview.getQueue/ activity.getQueueและได้รับสิ่งที่คุณต้องการโดยไม่ต้องมีโค้ดติดตามหรือตัวกรองของคุณเอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.