手写简易版handler

handler消息机制

手写简易版handler_第1张图片MyLooper

public class MyLooper {

    static final ThreadLocal<MyLooper> sThreadLocal = new ThreadLocal<>();
    public MyMessageQueue myQueue;

    public MyLooper(){
        myQueue = new MyMessageQueue();
    }

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

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

    public static void loop() {
        // 从全局ThreadLocalMap中获取唯一looper对象
        MyLooper myLooper = myLooper();
        MyMessageQueue myQueue = myLooper.myQueue;

        while (true) {
            MyMessage myMessage = myQueue.next();
            if (myMessage != null) {
                myMessage.target.dispatchMessage(myMessage);
            }
        }
    }
}

MyMessageQueue

public class MyMessageQueue {

    // 阻塞队列
    BlockingQueue<MyMessage> myMessages = new ArrayBlockingQueue<>(50);

    public MyMessageQueue() {

    }

    public void enqueueMessage(MyMessage message) {
        try {
            myMessages.put(message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 从消息队列中取出
    public MyMessage next() {
        try {
            return myMessages.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

MyMessage

public class MyMessage {

    Object obj;
    int what;
    MyHandler target;
}

MyHandler

public class MyHandler {

    private MyLooper myLooper;
    private MyMessageQueue myQueue;

    public MyHandler() {
        myLooper = MyLooper.myLooper();
        if (myLooper == null) {
            throw new RuntimeException(
                    "Can't create handler inside thread " + Thread.currentThread()
                            + " that has not called Looper.prepare()");
        }
        myQueue = myLooper.myQueue;
    }

    public void handleMessage(MyMessage msg) {

    }

    public void sendMessage(MyMessage message) {

        message.target = this;
        // 将消息放入到消息队列中
        myQueue.enqueueMessage(message);
    }

    public void dispatchMessage(MyMessage myMessage) {
        handleMessage(myMessage);
    }
}

main

    @Test
    public void handlerMain() {

        MyLooper.prepare();

        final MyHandler handler = new MyHandler(){
            @Override
            public void handleMessage(MyMessage msg) {
                super.handleMessage(msg);
                System.out.println(msg.obj.toString());
            }
        };

        new Thread(new Runnable() {
            @Override
            public void run() {
                MyMessage message = new MyMessage();
                message.obj = "消息";
                handler.sendMessage(message);
            }
        }).start();

        MyLooper.loop();
    }

运行结果
手写简易版handler_第2张图片

Thread, Handler, Looper, MessageQueue对应关系

安卓中一个线程只能初始化一次Looper对象,一个Looper对象中持有一个MessageQueue对象。所以Thread, Looper, MessageQueue是一对一关系。而Handler只是持有当前线程中Looper的引用。

ThreadLocal看这里

你可能感兴趣的:(java)