Android-手写Handler

2020-08-19  本文已影响0人  有腹肌的豌豆Z

Android消息机制相关类

Handler、Message、MessageQueue、Looper

ZHandler

public class ZHandler {

    private ZLooper myLooper;
    private ZMessageQueue myQueue;

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

    /**
     * 消息处理 Handler 实现 重写当前
     */
    public void handleMessage(ZMessage msg) {

    }

    /**
     * 发送消息
     */
    public void sendMessage(ZMessage message) {
        message.target = this;
        // 将消息放入到消息队列中
        myQueue.enqueueMessage(message);
    }

    /**
     * 消息分发 处理message的时候调用当前
     */
    public void dispatchMessage(ZMessage myMessage) {
        handleMessage(myMessage);
    }

}

ZLooper

public class ZLooper {

    /**
     * 当前线程保存数据对象
     */
    static final ThreadLocal<ZLooper> sThreadLocal = new ThreadLocal<>();

    /**
     * 消息队列
     */
    public ZMessageQueue myQueue;


    public ZLooper() {
        myQueue = new ZMessageQueue();
    }

    /**
     * 创建(准备)Looper
     */
    public static void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new ZLooper());
    }

    /**
     * 获取 当前 Looper
     */
    public static ZLooper myLooper() {
        return sThreadLocal.get();
    }

    /**
     * 启动 looper 注意这个有个死循环
     */
    public static void loop() {
        // 从全局ThreadLocalMap中获取唯一looper对象
        ZLooper myLooper = myLooper();
        ZMessageQueue myQueue = myLooper.myQueue;

        for (; ; ) {
            ZMessage myMessage = myQueue.next();
            Log.i(TAG, "loop: " + myMessage);
            if (myMessage != null) {
                myMessage.target.dispatchMessage(myMessage);
            }
        }
    }

}

ZMessageQueue

public class ZMessageQueue {

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

    public ZMessageQueue() {

    }

    /**
     * 将消息添加到队列
     */
    public void enqueueMessage(ZMessage message) {
        try {
            myMessages.put(message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

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

}

MainActivity 测试

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "SHARK_HANDLER";
    private int count;
    private ZHandler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        handlerMain();
    }
    
    public void handlerMain() {
        // 创建looper
        ZLooper.prepare();
        
        // 创建自己的Handler 
        handler = new ZHandler() {
            @Override
            public void handleMessage(ZMessage msg) {
                super.handleMessage(msg);
                Log.i(TAG, "handleMessage: 处理消息" + msg.obj);
            }
        };

        // 子线程发送消息
        new Thread(new Runnable() {
            @Override
            public void run() {

                while (true) {
                    ZMessage message = new ZMessage();
                    message.obj = "消息" + count;
                    count++;
                    handler.sendMessage(message);

                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        // 开启looper注意这里开启了死循环(模拟ActivityThread main函数里的)
        ZLooper.loop();
    }

}

数据结构队列

Queue

ThreadLocal

Demo

上一篇下一篇

猜你喜欢

热点阅读