Android: Sự khác biệt giữa Activity.runOnUiThread và View.post là gì?


97

Sự khác biệt giữa Activity.runOnUiThreadView.post, ai đó, xin vui lòng, giải thích?


Câu trả lời:


104

Không có sự khác biệt thực sự, ngoại trừ việc View.posthữu ích khi bạn không có quyền truy cập trực tiếp vào hoạt động.

Trong cả hai trường hợp, nếu không có trên chuỗi giao diện người dùng, Handler#post(Runnable)sẽ được gọi là hậu trường.

Như CommonsWare đã đề cập trong nhận xét, có sự khác biệt giữa hai - khi được gọi trên luồng Ui, Activity#runOnUiThreadsẽ gọi runphương thức trực tiếp, trong khi View#postsẽ đăng runnablelên hàng đợi (ví dụ: gọi Handler#post)

Điểm quan trọng IMO là cả hai đều có cùng mục tiêu và đối với bất kỳ ai sử dụng nó, không được có sự khác biệt (và việc triển khai có thể thay đổi trong tương lai).


70
Một điểm khác biệt: runOnUiThread()kiểm tra luồng hiện tại và thực thi Runnablengay lập tức nếu chúng ta tình cờ ở trên luồng ứng dụng chính. post()luôn đặt Runnablehàng đợi, bất kể nó được gọi theo luồng nào.
CommonsWare

Cảm ơn bạn, tôi hiện có thể thấy sự khác biệt dựa trên lời giải thích của bạn và nhận xét của @CommonsWare.
Alexander Kulyakhtin

4
@Ashwin: "Bạn nói runOnUiThread () thực thi Runnable ngay lập tức" - không, tôi không làm như vậy. Vui lòng đọc lại bình luận. Tôi đã nói " runOnUiThread()kiểm tra luồng hiện tại và thực thi Runnablengay lập tức nếu chúng tôi tình cờ ở trên luồng ứng dụng chính " (nhấn mạnh thêm). "Nó có nghĩa là những gì hiện có trên chuỗi giao diện người dùng bị bỏ qua và điều này được ưu tiên hàng đầu?" - "cái gì bao giờ hiện là trên thread UI" các runOnUiThread()cuộc gọi.
CommonsWare

1
@bar.gumbl: Trong trường hợp này, tôi đã xem xét nguồn.
CommonsWare

1
một sự khác biệt. Đăng lên một dạng xem không gắn với cửa sổ sẽ không làm được gì cả. Mặc dù không phải là một sự khác biệt lớn , điều này có thể gây ra các lỗi nhỏ và khá khó chịu để điều hướng nếu bạn không biết sự khác biệt tồn tại.
dcow

23

Một sự khác biệt khác giữa Activity.runOnUiThread và view.post () là runnable trong view.post () được gọi sau khi view được gắn vào một cửa sổ.


Làm thế nào để bạn có nghĩa là hiển thị? Trở nên hiển thị? Không được gọi là một cái nhìn vô hình ở tất cả?
Alexander Kulyakhtin

Đã sửa sự mơ hồ Alex.
pareshgoel

5
Đây là điểm khác biệt quan trọng nhất IMHO. Rất nhiều người sử dụng view.post () để thực thi nội dung cần được thực thi SAU KHI khung nhìn được đính kèm.
Sotti

3
Đây không phải là sự thật. Điều này chưa bao giờ đúng, nhưng tại một số điểm, JavaDoc cho View.java đã tuyên bố sai rằng "View.post chỉ hoạt động từ một luồng khác khi View được đính kèm với một cửa sổ". Điều này đã được khắc phục vào ngày 15 tháng 10 năm 2012, nhưng phải mất một thời gian để thâm nhập vào tâm trí của các nhà phát triển Android.
Alex Cohn

@pareshgoel nguồn cho sự khác biệt này?
apostleofzion

17

Hoặc là chấp nhận được đối với hầu hết các tình huống và phần lớn họ là hoán đổi cho nhau, nhưng họ một cách tinh tế khác nhau. Sự khác biệt lớn nhất tất nhiên là một cái có sẵn từ một Activityvà cái kia từ a View. Có rất nhiều sự chồng chéo giữa những thứ đó, nhưng đôi khi trong một tập Activitybạn sẽ không có quyền truy cập vào một Viewvà đôi khi trong một tập Viewbạn sẽ không có quyền truy cập vào một Activity.

Một trong những trường hợp phức tạp mà tôi đã gặp mà View.posttôi đã đề cập trong câu trả lời cho một câu hỏi SO khácView.post : View.postchỉ hoạt động từ một luồng khác khi luồngView được gắn vào một cửa sổ. Điều này hiếm khi là một vấn đề, nhưng đôi khi có thể khiến Runnablenó không bao giờ thực thi, đặc biệt nếu bạn gọi View.posttrong onCreatephương thức của bạn Activity. Một giải pháp thay thế là sử dụng Handler.postcái nào là cái gì Activity.runOnUiThreadView.postdù sao cũng sử dụng dưới các trang bìa.

(đã chỉnh sửa cho chính xác, được thêm vào "từ một chủ đề khác")


1
Nó có thể thất bại khi không được đính kèm trong onCreate()cũng? Hm, tôi mong rằng nó sẽ được đăng lên người Handlerđược cung cấp ViewRoottrong trường hợp đó.
Jens

5
@Jens Vâng, tôi đã xem qua nguồn và View.postnên thêm Runnablevào hàng đợi để thực thi sau nếu nó chưa được đính kèm. Tôi chưa tìm hiểu sâu hơn về nguồn, nhưng các tài liệu cho biết: "Phương thức này chỉ có thể được gọi từ bên ngoài chuỗi giao diện người dùng khi Chế độ xem này được đính kèm với một cửa sổ." Vì vậy, tôi nghĩ nếu nó trên chủ đề hiện tại, thì những gì bạn nói là đúng, nếu không phải thì nó có thể nuốt chửng Runnable. Tôi chắc chắn đã có điều đó xảy ra trong mã của mình.
kabuko

@kabuko Cảm ơn bạn câu trả lời của bạn cho thấy nó ở một điểm khác. Nó là như thế nào Tôi không thể chấp nhận nhiều hơn 1 câu trả lời không thể thấy logic đằng sau điều đó sẽ đăng trên diễn đàn meta
Alexander Kulyakhtin

3
Đây không phải là sự thật. Điều này chưa bao giờ đúng, nhưng tại một số điểm, JavaDoc cho View.java đã tuyên bố sai rằng "View.post chỉ hoạt động từ một luồng khác khi View được đính kèm với một cửa sổ". Điều này đã được khắc phục vào ngày 15 tháng 10 năm 2012, nhưng phải mất một thời gian để thâm nhập vào tâm trí của các nhà phát triển Android.
Alex Cohn

0

Một sự khác biệt khác: postlà mỗi Lượt xem; runOnUiThreadlà mỗi Hoạt động.

Điều này có nghĩa là bạn sẽ có thể (trong tương lai?) Làm view.getQueue/ activity.getQueuevà nhận được chính xác những gì bạn muốn mà không cần mã theo dõi hoặc lọc của riêng bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.