参照源码自己手写Handler

目录

TestHandler.java

TestMessageQueue.java

TestLooper.java

TestMessage.java

使用:TestHandlerMain.java  测试


TestHandler.java

public class TestHandler {
    final TestMessageQueue mQueue;
    final TestLooper mLooper;

    public TestHandler() {
        //解答: 首先,线程是唯一的,ThreadLocal能够确保Looper唯一,进而确保MessageQueue唯一。
        mLooper = TestLooper.myLooper(); 
        mQueue = mLooper.mQueue;  
    }

    /**
     * 发送消息
     */
    public void sendMessage(TestMessage message) {
        enqueueMessage(message);
    }

    public void enqueueMessage(TestMessage message) {
        message.target = this;
        mQueue.enqueueMessage(message);
    }

    //分发消息
    public void dispatchMessage(TestMessage message) {
        handleMessage(message);
    }

    //处理消息
    public void handleMessage(TestMessage message) {

    }

}

TestMessageQueue.java

public class TestMessageQueue {

    //实现仓库的阻塞队列
    BlockingQueue queue;
    //仓库大小
    private static final int MAXCOUNT = 10;

    public TestMessageQueue() {
        queue = new ArrayBlockingQueue(MAXCOUNT);
    }

    /**
     * 往消息队列添加消息
     * 入队:根据时间排序,当队列满的时候,阻塞,直到用户通过next取出消息。当next方法被调用,
     * 通知MessageQueue可以进行消息的入队
     */
    public void enqueueMessage(TestMessage message) {
        //因为是阻塞的,所以要用try-catch
        try {
            queue.put(message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从消息队列取消息
     * 出队:由Looper.loop(),启动轮询器,对queue进行轮询。当消息达到执行时间就取出来。
     * 当messageQueue为空的时候,队列阻塞,等消息队列调用enqueueMessage的时候,通知队列,可以取出消息,停止阻塞。
     */
    public TestMessage next() {
        TestMessage msg = null;
        try {
            msg = queue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return msg;
    }

}

TestLooper.java

public class TestLooper {

    public TestMessageQueue mQueue;
    public static ThreadLocal sThreadLocal = new ThreadLocal<>();

    private TestLooper() {
        mQueue = new TestMessageQueue();

    }

    public static void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new TestLooper());
    }

    public static TestLooper myLooper() {
        return sThreadLocal.get();
    }

    /**
     * 启动Looper,让messageQueue 运行
     */
    public static void loop() {
        // 首先,线程是唯一的,ThreadLocal能够确保Looper唯一,进而确保MessageQueue唯一。
        final TestLooper me = myLooper();
        final TestMessageQueue queue = me.mQueue;
        for (; ; ) {
            TestMessage msg = queue.next();
            if (msg!=null){
                msg.target.dispatchMessage(msg);
            }
        }


    }


}

TestMessage.java

public class TestMessage {

    TestHandler target;

    Object obj;

    public TestMessage(){

    }

    @Override
    public String toString() {
        return obj.toString();
    }

}

使用:TestHandlerMain.java  测试

public class TestHandlerMain {

    public static void main(String[] args) {

        //如果不加上这句,TestLooper会报空指针错误
        TestLooper.prepare();
        final TestHandler handler = new TestHandler() {
            @Override
            public void handleMessage(TestMessage message) {
                System.out.println(Thread.currentThread().toString()
                        + " --received msg:" + message.toString());
            }
        };

        //单线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    TestMessage msg = new TestMessage();
                    msg.obj = UUID.randomUUID().toString();
                    System.out.println(Thread.currentThread().toString() + " --send msg:" + msg.toString());
                    handler.sendMessage(msg);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();


        TestLooper.loop();

    }

}

 

你可能感兴趣的:(Android:Handler)