java中手写handler_手写Handler架构

在了解Handler原理的同时可以翻看源码研究一下Handler架构,下面是本人手写的Handler架构

Message.javapublic class Message {

int what;

Handler target;

}

Message类我写的很简单,源码中是有很多代码的,这里能够传递值的参数只有what。target对象主要是为了最终能够执行到handleMessage回调方法,具体作用可以在下文代码中可以看到。

MessageQueue.java/**

*  互斥队列的通用类

*/public class MessageQueue {    //声明阻塞队列

private BlockingDeque blockingDeque = new LinkedBlockingDeque(50);    /**

* 入队(生产者)

* @param msg

* @return

*/

public void enqueueMessage(Message msg) {        if (msg.target == null) {            throw new IllegalArgumentException("Message must have a target.");

}        try {

blockingDeque.put(msg);

} catch (InterruptedException e) {

e.printStackTrace();

}

}    /**

* 出队(消费者)

* @return

*/

public Message next() {

Message msg = null;        try {

msg = (Message) blockingDeque.take();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (Exception e){

e.printStackTrace();

}        return msg;

}

}

MessageQueue类其实是最核心的地方了,这是一个消息队列,只有两种行文,出队和入队。并且,这是一个生产者、消费者设计模式。BlockingDeque是阻塞队列,在生产者、消费者设计模式中的运用比较常见。

Looper.javapublic class Looper {    static MessageQueue mQueue;    private static ThreadLocal sThreadLocal = new ThreadLocal();    private Looper() {

mQueue = new MessageQueue();

}    public 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(){        for(;;){

Message msg = mQueue.next();            if(msg == null){                continue;

}

msg.target.dispatchMessage(msg);

}

}

}

Looper中含有一个消息队列,looper只负责一个任务,那就是无限遍历消息队列,如果队列中有消息,就从队首取出消息,传递给handleMessage回调方法。这里的dispatchMessage方法就是为了执行Handler的回调方法handleMessage。

Handler.javapublic class Handler {

private MessageQueue mQueue;    public Handler() {

Looper.prepare();

Looper looper = Looper.myLooper();

mQueue = looper.mQueue;

}    public void handleMessage(Message msg) {

}    public void dispatchMessage(Message msg){

handleMessage(msg);

}    public void sendMessage(Message msg){

MessageQueue queue = mQueue;        if (queue != null) {

enqueueMessage(queue, msg);

}

}    private void enqueueMessage(MessageQueue mQueue, Message msg){

msg.target = this;

mQueue.enqueueMessage(msg);

}

}

Handler负责将消息放进消息队列中,也就是所谓了入队了,sendMessage方法就是让消息入队。

Test.javapublic class Test {    private static Handler handler = new Handler(){        @Override

public void handleMessage(Message msg) {            super.handleMessage(msg);

System.out.println(String.valueOf(msg.what));

}

};    public static void main(String[] args){        new Thread(new Runnable() {            @Override

public void run() {                for(int i=0;i<100;i++){

Message message = new Message();

message.what = i;

handler.sendMessage(message);

}

}

}).start();

Looper.loop();

}

}

Looper.loop()这个方法不能放入Activity的UI线程,否则会阻塞,这里我新建一个java的启动入口, 我们只需要执行main方法就可以了。

在底层中,ActivityThread是UI线程, Android的启动入口就是这个类的main方法,main方法中已经声明了LooperLooper.prepareMainLooper();Looper.loop();

AAffA0nNPuCLAAAAAElFTkSuQmCC

图片.png

作者:NoBugException

链接:https://www.jianshu.com/p/92c8495c6ab1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值