模擬Android Handler機制——單執行緒處理多工
阿新 • • 發佈:2019-02-20
訊息類(Message):
訊息佇列(MessageQueue):package p; public class Message { private Runnable runnable; private long start; private long delay; public Message(Runnable runnable, long delay) { start = System.currentTimeMillis(); this.runnable = runnable; this.delay = delay; } public void handle() { runnable.run(); } public boolean canHandle() { return delay <= System.currentTimeMillis() - start; } }
package p; import java.util.ArrayList; import java.util.List; public class MessageQueue { private List<Message> messages = new ArrayList<Message>(); private int cursor = -1; /** * 入隊 * * @param message */ public void push(Message message) { messages.add(message); } /** * 移出佇列 * * @param message */ public void remove(Message message) { messages.remove(message); cursor--; } /** * 出隊 * * @return */ public Message pop() { Message message = null; if (!messages.isEmpty()) { message = messages.get(++cursor); if (cursor == messages.size() - 1) { cursor = -1; } } return message; } }
每個執行緒擁有一個訊息佇列。
訊息管理類(MessageManager):
package p; public class MessageManager { private static ThreadLocal<MessageQueue> local = new ThreadLocal<MessageQueue>(); /** * 訊息入隊 * @param message */ public static void addMessage(Message message) { local.get().push(message); } /** * 建立訊息佇列 */ public static void prepare() { MessageQueue queue = local.get(); if (queue != null) { throw new RuntimeException("每個執行緒只能有一個訊息佇列!"); } local.set(new MessageQueue()); } /** * 開啟訊息迴圈 */ public static void loop() { MessageQueue messageQueue = local.get(); Message message; while ((message = messageQueue.pop()) != null) { if (message.canHandle()) { messageQueue.remove(message); message.handle(); } } } }
模擬handler類(Handler):
package p;
public class Handler {
public void post(Runnable runnable, long delay) {
Message message = new Message(runnable, delay);
MessageManager.addMessage(message);
}
}
模擬activity的類(MainUI):package p;
public class MainUI {
public void onCreate() {
System.out.println("onCreate:" + Thread.currentThread().getName());
new Handler().post(new Runnable() {
@Override
public void run() {
System.out.println("post after 3 minutes:"
+ Thread.currentThread().getName());
}
}, 3000);
new Handler().post(new Runnable() {
@Override
public void run() {
System.out.println("post after 6 minutes:"
+ Thread.currentThread().getName());
}
}, 6000);
new Thread(new Runnable() {
@Override
public void run() {
MessageManager.prepare();
new Handler().post(new Runnable() {
@Override
public void run() {
System.out.println("post after 9 minutes:"
+ Thread.currentThread().getName());
}
}, 9000);
new Handler().post(new Runnable() {
@Override
public void run() {
System.out.println("post after 12 minutes:"
+ Thread.currentThread().getName());
}
}, 12000);
MessageManager.loop();
}
}).start();
System.out.println("End onCreate!");
}
}
模擬android啟動activity的類(Main):package p;
public class Main {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
MessageManager.prepare();
MainUI mainUI = new MainUI();
mainUI.onCreate();
MessageManager.loop();
}
};
Thread main = new Thread(runnable);
main.setName("main");
main.start();
}
}
執行輸出:onCreate:main
End onCreate!
post after 3 minutes:main
post after 6 minutes:main
post after 9 minutes:Thread-1
post after 12 minutes:Thread-1