Bạn có thể hiểu rõ hơn Looper là gì trong bối cảnh GUI GUI. Looper được thực hiện để làm 2 việc.
1) Looper biến đổi một luồng bình thường , kết thúc khi phương thức run () của nó trở lại, thành một thứ gì đó chạy liên tục cho đến khi ứng dụng Android chạy , cần thiết trong khung GUI (Về mặt kỹ thuật, nó vẫn chấm dứt khi phương thức run () quay lại. làm rõ những gì tôi muốn nói ở bên dưới)
2) Looper cung cấp một hàng đợi trong đó các công việc phải hoàn thành được yêu cầu, điều này cũng cần thiết trong khung GUI.
Như bạn có thể biết, khi một ứng dụng được khởi chạy, hệ thống sẽ tạo ra một luồng thực thi cho ứng dụng, được gọi là chính main, và các ứng dụng Android thường chạy hoàn toàn trên một luồng theo mặc định là chủ đề chính của chanh. Nhưng chủ đề chính không phải là một số chủ đề bí mật, đặc biệt . Nó chỉ là một luồng bình thường tương tự như các luồng bạn tạo bằng new Thread()
mã, có nghĩa là nó kết thúc khi phương thức run () của nó trả về! Hãy nghĩ về ví dụ dưới đây.
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Bây giờ, hãy áp dụng nguyên tắc đơn giản này cho các ứng dụng Android. Điều gì sẽ xảy ra nếu một ứng dụng Android chạy trên luồng bình thường? Một chuỗi được gọi là "chính" hoặc "Giao diện người dùng" hoặc bất cứ điều gì khởi động ứng dụng của bạn và rút ra tất cả giao diện người dùng. Vì vậy, màn hình đầu tiên được hiển thị cho người dùng. Giờ thì sao? Chủ đề chính chấm dứt? Không, nó không nên. Nó sẽ đợi cho đến khi người dùng làm một cái gì đó, phải không? Nhưng làm thế nào chúng ta có thể đạt được hành vi này? Vâng, chúng ta có thể thử với Object.wait()
hoặcThread.sleep()
. Ví dụ, luồng chính hoàn thành công việc ban đầu để hiển thị màn hình đầu tiên và ngủ. Nó thức dậy, có nghĩa là bị gián đoạn, khi một công việc mới phải làm được tìm nạp. Cho đến nay là tốt, nhưng tại thời điểm này, chúng ta cần một cấu trúc dữ liệu giống như hàng đợi để giữ nhiều công việc. Hãy suy nghĩ về một trường hợp khi người dùng chạm vào màn hình một cách thanh thản và một tác vụ mất nhiều thời gian hơn để hoàn thành. Vì vậy, chúng ta cần phải có một cấu trúc dữ liệu để giữ các công việc phải được thực hiện theo cách trước xuất trước. Ngoài ra, bạn có thể tưởng tượng, việc thực hiện luồng luôn chạy và xử lý công việc khi đến bằng cách sử dụng ngắt là không dễ dàng, và dẫn đến mã phức tạp và thường không thể nhầm lẫn. Chúng tôi muốn tạo ra một cơ chế mới cho mục đích như vậy và đó là tất cả những gì Looper hướng tới . Các tài liệu chính thức của lớp Loopernói, "Chủ đề theo mặc định không có vòng lặp thông báo liên quan đến chúng" và Looper là một lớp "được sử dụng để chạy vòng lặp thông báo cho một chuỗi". Bây giờ bạn có thể hiểu ý nghĩa của nó.
Để làm cho mọi thứ rõ ràng hơn, hãy kiểm tra mã nơi chuyển đổi luồng chính. Tất cả xảy ra trong lớp ActivityThread . Trong phương thức main () của nó, bạn có thể tìm thấy đoạn mã bên dưới, biến một luồng chính bình thường thành thứ chúng ta cần.
public final class ActivityThread {
...
public static void main(String[] args) {
...
Looper.prepareMainLooper();
Looper.loop();
...
}
}
và Looper.loop()
phương thức lặp vô hạn và xử lý một thông báo và xử lý từng thông báo một:
public static void loop() {
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
msg.target.dispatchMessage(msg);
...
}
}
Vì vậy, về cơ bản Looper là một lớp được tạo ra để giải quyết vấn đề xảy ra trong khung GUI. Nhưng loại nhu cầu này cũng có thể xảy ra trong tình huống khác. Trên thực tế, đây là một mẫu khá nổi tiếng cho ứng dụng đa luồng và bạn có thể tìm hiểu thêm về nó trong " Lập trình đồng thời trong Java " của Doug Lea (Đặc biệt, chương 4.1.4 "Chủ đề công nhân" sẽ hữu ích). Ngoài ra, bạn có thể tưởng tượng loại cơ chế này không phải là duy nhất trong khung Android, nhưng tất cả khung GUI có thể cần hơi giống với điều này. Bạn có thể tìm thấy cơ chế gần như tương tự trong khung công tác Java Swing.