Tôi có một chuỗi công nhân nằm trong nền, xử lý tin nhắn. Một cái gì đó như thế này:Cách tạo chủ đề Looper, sau đó gửi tin nhắn ngay lập tức?
class Worker extends Thread {
public volatile Handler handler; // actually private, of course
public void run() {
Looper.prepare();
mHandler = new Handler() { // the Handler hooks up to the current Thread
public boolean handleMessage(Message msg) {
// ...
}
};
Looper.loop();
}
}
Từ các chủ đề chính (UI chủ đề, không phải là vấn đề) Tôi muốn làm điều gì đó như thế này:
Worker worker = new Worker();
worker.start();
worker.handler.sendMessage(...);
Vấn đề là điều này đặt tôi lên một điều kiện đua đẹp: tại thời điểm worker.handler
được đọc, không có cách nào để đảm bảo rằng chuỗi công nhân đã được gán cho trường này!
Tôi không thể tạo đơn giản Handler
từ hàm tạo của Worker
, bởi vì hàm tạo chạy trên luồng chính, do đó Handler
sẽ tự kết hợp với chuỗi sai.
Điều này hầu như không giống như một trường hợp không phổ biến. Tôi có thể đưa ra nhiều cách giải quyết, tất cả trong số họ xấu xí:
Something như thế này:
class Worker extends Thread { public volatile Handler handler; // actually private, of course public void run() { Looper.prepare(); mHandler = new Handler() { // the Handler hooks up to the current Thread public boolean handleMessage(Message msg) { // ... } }; notifyAll(); // <- ADDED Looper.loop(); } }
Và từ các chủ đề chính:
Worker worker = new Worker(); worker.start(); worker.wait(); // <- ADDED worker.handler.sendMessage(...);
Nhưng điều này là không đáng tin cậy hoặc : nếu
notifyAll()
xảy ra trướcwait()
, thì chúng tôi sẽ không bao giờ bị đánh thức!Chuyển số
Message
ban đầu cho hàm tạoWorker
, có phương thứcrun()
đăng nó. Một giải pháp đặc biệt, sẽ không hoạt động đối với nhiều thư hoặc nếu chúng tôi không muốn gửi ngay nhưng ngay sau đó.Bận chờ đến khi trường
handler
không còn lànull
. Yep, một phương sách cuối cùng ...
Tôi muốn tạo ra một Handler
và MessageQueue
thay mặt cho chủ đề Worker
, nhưng điều này dường như không thực hiện được. Cách thanh lịch nhất trong số này là gì?
Bất kỳ lý do cụ thể bạn đang không sử dụng 'HandlerThread'? – CommonsWare
@CommonsWare: Hmm, không biết rằng nó đã tồn tại. Không có tham chiếu chéo trong tài liệu. Phương thức 'getLooper()' của nó cho đến khi chúng ta có một 'Looper', sau đó chúng ta có thể sử dụng' Trình xử lý mới (worker.getLooper()) '* từ chuỗi chính * để khởi tạo' Trình xử lý '. Điều đó sẽ giải quyết vấn đề, đúng không? – Thomas
Tôi nghĩ vậy. OTOH, tôi không sử dụng nó nhiều, và vì vậy tôi có thể thiếu một cái gì đó. – CommonsWare