Android Looper BlockingQueue
In Android, the Looper class is responsible for creating a message loop that processes messages in a thread. It is often used in conjunction with the Handler class to perform asynchronous tasks and update the user interface. One important component of the Looper class is the BlockingQueue, which is used to store and retrieve messages.
What is a BlockingQueue?
A BlockingQueue is a thread-safe queue that supports operations such as put and take. It blocks the thread if the queue is empty (for take) or full (for put), until the queue becomes non-empty or non-full. This behavior makes it ideal for inter-thread communication, where one thread produces messages and another thread consumes them.
The BlockingQueue interface provides several implementations, such as ArrayBlockingQueue, LinkedBlockingQueue, and PriorityBlockingQueue. Each implementation has its own characteristics and use cases, but in the context of the Looper class, the LinkedBlockingQueue is commonly used.
How does Looper use BlockingQueue?
The Looper class uses a BlockingQueue to store messages that are sent to it. When a Handler sends a message to a Looper, the message is added to the BlockingQueue using the enqueueMessage
method. The Looper's thread is constantly running a loop that retrieves messages from the BlockingQueue using the next()
method.
Here's an example that demonstrates the usage of Looper and BlockingQueue:
public class MyLooperThread extends Thread {
private Looper looper;
@Override
public void run() {
Looper.prepare();
looper = Looper.myLooper();
Looper.loop();
}
public Looper getLooper() {
return looper;
}
}
public class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
// Handle the message here
}
}
public class MainThread {
public static void main(String[] args) {
MyLooperThread looperThread = new MyLooperThread();
looperThread.start();
// Wait for the looper thread to prepare the Looper
while (looperThread.getLooper() == null) {
Thread.sleep(10);
}
Looper looper = looperThread.getLooper();
MyHandler handler = new MyHandler();
// Create and send messages to the Looper
for (int i = 0; i < 10; i++) {
Message message = new Message();
message.what = i;
handler.sendMessage(message);
}
// Stop the Looper after sending all messages
looper.quit();
}
}
In this example, we first create a MyLooperThread
that extends Thread
and overrides the run()
method. Inside the run()
method, we call Looper.prepare()
to prepare the Looper for the thread and then call Looper.loop()
to start the message loop.
Next, we create a MyHandler
that extends Handler
and overrides the handleMessage()
method. Inside this method, we can handle the messages sent to the Looper.
In the MainThread
class, we start the MyLooperThread
and wait for the Looper to be prepared. Once it is prepared, we obtain the Looper instance and create a MyHandler
instance. We then create and send messages to the Looper using the sendMessage()
method of the handler.
Finally, we stop the Looper by calling looper.quit()
after sending all the messages.
Conclusion
The Looper class, together with the BlockingQueue, provides a convenient way to implement message passing and asynchronous tasks in Android. It allows threads to communicate and perform tasks without blocking or freezing the user interface. Understanding how the Looper class uses the BlockingQueue is essential for developing efficient and responsive Android applications.
表格
Class | Description |
---|---|
Looper |
Provides a message loop for a thread |
BlockingQueue |
A thread-safe queue that supports blocking operations |
ArrayBlockingQueue |
A bounded BlockingQueue backed by an array |
LinkedBlockingQueue |
An optionally-bounded BlockingQueue backed by a linked list |
PriorityBlockingQueue |
An unbounded blocking queue that uses the same ordering rules as class PriorityQueue |
![Journey](mermaid journey title Android Looper BlockingQueue Journey section Understanding BlockingQueue UnderstandingBlockingQueue-->UsingBlockingQueue section Using BlockingQueue UsingBlockingQueue-->PuttingMessages UsingBlockingQueue-->TakingMessages section Putting Messages PuttingMessages-->BlockingIfFull section Taking Messages TakingMessages-->BlockingIfEmpty )