自己实现一下handler机制

自己实现一下handler机制,加深理解知识

发布日期 2018-03-26

前面已经了解了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 成功!