2012-06-25 30 views
18

Tôi có một dịch vụ Android khởi động và duy trì một chuỗi nền.Thực thi mã trên chuỗi chính trong Android mà không cần truy cập vào Hoạt động?

Thỉnh thoảng, chuỗi nền cần thực hiện gọi lại trên chuỗi chính. Tôi đang bối rối như thế nào để làm điều này.

Tôi không thể gọi điều này.runOnUiThread vì "this" là phiên bản của Dịch vụ chứ không phải Activity và Service không có phương thức runOnUiThread.

Tôi cũng không thể tạo hoặc thực thi AsyncTask, vì tài liệu cho AsyncTask nói rằng cả hàm tạo và phương thức thực hiện phải được gọi từ chuỗi giao diện người dùng.

Tôi có cần duy trì tham chiếu đến hoạt động đang sử dụng dịch vụ và gọi phương thức runOnUiThread của nó hay có cách nào khác để chạy một thứ gì đó trên chuỗi giao diện người dùng không?

Cảm ơn.

+3

"chủ đề nền cần thực hiện gọi lại trên chuỗi chính" - tại sao? – CommonsWare

+0

Người dùng dịch vụ là hoạt động. Nó cần gọi lại trên chuỗi chính để nó có thể cập nhật các phần tử giao diện người dùng. Tôi cho rằng tôi có thể gọi nó trở lại trên chủ đề nền và làm cho nó có trách nhiệm lên lịch một cuộc gọi lại trong chuỗi giao diện người dùng, nhưng nó sẽ thuận tiện hơn cho người tiêu dùng của dịch vụ nếu tôi có thể làm điều đó. –

+3

@Cruceo: Ồ, trời không. – CommonsWare

Trả lời

2

Hoạt động của bạn phải có thể liên kết với dịch vụ.

http://developer.android.com/guide/components/bound-services.html

Cụ thể, hãy nhìn vào việc tạo ra một Messenger trên trang đó. Hoạt động của máy khách có thể cung cấp cho một đối tượng messenger phản hồi các thông điệp từ dịch vụ và sau khi nhận được, hãy chạy bất kỳ mã UI nào là cần thiết trên luồng giao diện người dùng bằng cách sử dụng một trình xử lý.

KHÔNG giữ tham chiếu của hoạt động trong dịch vụ. Điều này có thể dẫn đến tất cả các loại vấn đề về bộ nhớ.

+0

Trong khi 'Messenger' là một giải pháp tốt, bạn không phải liên kết với dịch vụ để sử dụng nó. 'Messenger' là' Parcelable' và có thể được gửi trong 'Intent' thêm trong một lệnh được gửi qua' startService() '. – CommonsWare

1

Chắc chắn. Xem Handler. Bạn có thể cung cấp cho dịch vụ của bạn một đối tượng xử lý và khi dịch vụ cần chạy một số nhiệm vụ Runnable trên chuỗi giao diện người dùng chỉ cần gọi handler.post (some_runnable_task). Cuộc gọi này. Có thể tìm thấy ví dụ trong số link 4.Hướng dẫn: Trình xử lý này.

9

Cần gọi lại trên chuỗi chính để có thể cập nhật phần tử giao diện người dùng.

Sử dụng LocalBroadcastManager và yêu cầu dịch vụ gửi một hoạt động phát sóng, sẽ được tải lên theo chuỗi ứng dụng chính. Here is a sample application demonstrating this.

Hoặc, sử dụng chương trình phát sóng "thực" với sendBroadcast().

Hoặc sử dụng Messenger, như bạn đã đề cập, gắn với Handler, như Guillermo đã đề cập, mặc dù bạn không nhất thiết phải sử dụng ràng buộc cho nó.

53

Tôi thỉnh thoảng sử dụng mã sau nếu tôi không có quyền truy cập trực tiếp vào Hoạt động (vì lý do này hay cách khác);

new Handler(Looper.getMainLooper()).post(mYourUiThreadRunnable); 
+4

Tôi nghĩ rằng nó có thể đã lỗi thời, nhưng vẫn còn vào cuối năm 2015 đây là cách được đề nghị: http://developer.android.com/training/multiple-threads/communicate-ui.html – gaborsch

Các vấn đề liên quan