1. 程式人生 > >模擬Android Handler機制——單執行緒處理多工

模擬Android Handler機制——單執行緒處理多工

訊息類(Message):
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;
	}
}
訊息佇列(MessageQueue):
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