Android 学习随笔 Handler

Handler源码的几个核心类

  Handler、Message、Looper、MessageQueue

Handler发送到收到回调的完整流程

  

 

 Handler

  1:Handler的构造函数

public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
        mLooper = looper;//持有当前线程的Looper
        mQueue = looper.mQueue;//持有当前线程的Looper内的MessageQueue
        mCallback = callback;//接口回调
        mAsynchronous = async;//是否同步
    }

  2:Handler过时默认函数 空参数构造方法会调用Looper.myLooper()获取当前线程的Looper

  3:Handler会持有当前线程的Looper以及Looper里面的MessageQueue还有回调接口实现对象

Message

  1、Message的构造方法 

  官方不建议直接使用Message()方式创建Message对象 推荐使用Message.obtain方法创建
public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

  

  1.1 关于Message的sPool   Message包含有一个Message属性next 所以Message是一个链表 sPool会进行一个Message对象回收工作  在recycleUnchecked()方法里面进行回收

  1.2 Message的回收创建模式采用享元模式

  1.3 Message的一个一个属性 Handler target 会保存当前发送Message的Handler对象 方便looper取出数据将相应的message发送给对应的Handler的Callback 

MessageQueue

  1 MessageQueue是一个单向链表

  2 MessageQueue内部的next方法内部会调用一个native的方法 nativePollOnce(ptr, nextPollTimeoutMillis);  MessageQueue没有数据就会在这里被阻塞

 

Looper

  1 Looper的构造方法 及为什么一个线程只有一个Looper的原因

//私有构造方法 需要调用静态方法prepare()才能创建  类似单例模式
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }

 

private static void prepare(boolean quitAllowed) {
  //用ThreadLocal来保存当前Looper 和抛异常的方式达到当前线程只有一个Looper的目的
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

  

  2 Looper重要函数loop()  以及loopOnce()   loop内死循环调用loopOnce()方法轮询MessageQueue内的数据  如果MessageQueue没有数据就会被MessageQueue的next()内部阻塞

public static void loop() {
        final Looper me = myLooper();
     ...other//其他代码
        for (;;) {
            if (!loopOnce(me, ident, thresholdOverride)) {
                return;
            }
        }
    }
private static boolean loopOnce(final Looper me,
            final long ident, final int thresholdOverride) {
            ...//other
        
            msg.target.dispatchMessage(msg);
            ...other//

        return true;
    }

  

主线程(ActivithThread)中Looper的创建  

  1.ActivityThread的main()方法里面 

public static void main(String[] args) {       
     //这里创建主线程的Looper 
        Looper.prepareMainLooper();
    //调用Looper.loop()执行死循环 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }

  

 

  

posted @ 2022-05-11 11:56  bg_不够  阅读(49)  评论(0编辑  收藏  举报