Android Handler机制

2020-08-07  本文已影响0人  京写
handler机制图解
  1. handler线程安全的
  2. handler怎么用

Android UI线程ActivityThread.main会默认创建一个looper,默认调用looper.prepare和looper.loop方法
如果想在子线程中建立Handler来处理业务,需要手动先调用Looper.prepare方法,之后创建Handler,最后在调用Looper.loop方法。

实例代码

// 创建一个子线程,并在子线程中创建一个Handler,且重写handleMessage
        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                subHandler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        // 处理消息
                        switch (msg.what) {
                            case MSG_MAIN_TO_SUB:
                                Log.e(TAG, "接收到消息: " +  Thread.currentThread().getName() + ","+ msg.obj);
                                break;
                            default:
                                break;
                        }
                    }
                };
                Looper.loop();
            }
        }).start();

这样可以实现从主线程向子线程发送消息。
Looper:一个线程最多只存在一个Looper对象,如果没有,去创建一个Looper,并存放在sThreadLocal中。

  public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        // 规定了一个线程只有一个Looper,也就是一个线程只能调用一次Looper.prepare()
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        // 如果当前线程没有Looper,那么就创建一个,存到sThreadLocal中
        sThreadLocal.set(new Looper(quitAllowed));
    }

Looper会创建一个MessageQueue对象

 private Looper(boolean quitAllowed) {
        // 创建了MessageQueue,并供Looper持有
        mQueue = new MessageQueue(quitAllowed);
        // 让Looper持有当前线程对象
        mThread = Thread.currentThread();
    }

MessageQueue存放Message

Looper.loop

  public static void loop() {
        // 得到当前线程的Looper对象
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        // 得到当前线程的MessageQueue对象
        final MessageQueue queue = me.mQueue;
        
        // 无关代码
        ......
        
        // 死循环
        for (;;) {
            // 不断从当前线程的MessageQueue中取出Message,当MessageQueue没有元素时,方法阻塞
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            // Message.target是Handler,其实就是发送消息的Handler,这里就是调用它的dispatchMessage方法
            msg.target.dispatchMessage(msg);
            // 回收Message
            msg.recycleUnchecked();
        }
    }

Message信息携带者,一个线程可以有多个
Handler发送消息以及消息的回调实现,一个线程可以有多个Handler
Looper消息遍历者,从MessageQueue中循环取出Message进消息行处理,一个线程只有一个
MessageQueue消息队列,存放Handler发送消息,供Looper循环取消息,一个线程只有一个
sendMessageDelayed方法最终都是会被调到,只是延迟时间可能为0,

Handler相关面试问题

上一篇 下一篇

猜你喜欢

热点阅读