前面已经了解了Handler原理,如果能手写一个简单的Handler那就真的掌握啦,现在就开始写一个吧
根据前面的分析,可以知道这里涉及到了几个类,ActivityThread,Message,MessageQueue,Handler,Looper。
因为Activity在启动后ActivityThread这个类的main方法就已经执行完了
所以我们直接在工程的test文件夹下面创建一个ActivityThread来模拟Activity的入口。
public class ActivityThread {
@Test
public void main(){
//准备looper
Looper.prepareMainLooper();
//创建Handler
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//处理消息
System.out.println(msg.obj.toString());
}
};
//开启一个线程 从子线程中发送消息
new Thread(){
@Override
public void run() {
super.run();
//发从消息
Message msg = new Message();
msg.obj = "Hello Handler";
handler.sendMessage(msg);
}
}.start();
//开启循环
Looper.loop();
}
}
很简单就按照之前分析的四步来,
(1)准备Looper,
(2)创建Handler重写handleMessage方法处理消息,
(3)发送消息,
(4)开启循环处理消息。
Message类:
public class Message {
public int what;
public Handler target;
/**
* 消息对象
*/
public Object obj;
@Override
public String toString() {
return obj.toString();
}
}
MessageQueue类,使用一个阻塞队列ArrayBlockingQueue来模拟。
public class MessageQueue {
private ArrayBlockingQueue<Message> mMessages = new ArrayBlockingQueue<Message>(50);
//消息入队
public void enqueueMessage(Message msg) {
try {
mMessages.put(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//取消息
public Message next() {
try {
return mMessages.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
Looper类
public class Looper {
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
MessageQueue mQueue;
public Looper() {
mQueue = new MessageQueue();
}
public static void prepareMainLooper() {
prepare();
}
private static void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
public static Looper myLooper() {
return sThreadLocal.get();
}
//开启循环
public static void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true){
Message msg = queue.next();
if(msg!=null){
if(msg.target!=null){
msg.target.dispatchMessage(msg);
}
}
}
}
}
OK完成啦,在ActivityThread这个测试类中直接运行代码可以看到日志中输出 Hello Handler 成功!