android的消息机制

前置:一个线程一个looper,1个looper一个messageQueue,一个messageQueue对应多个Message;一个messageQueue可以对应多个handler(一般消息队列中Looper是一个无限循环的操作,但是当队列中没有消息时,会阻塞沉睡,等待有消息时被唤醒)

一:messageQueue:它是一个单项的链表,方便插入,删除,里面存了很多个message,每个message都相当于一个链表上的点,通过Message中的next指向下一个消息,

     不管是通过sendMessage还是postMesssage进行发送消息,它底层都是通过enqueueMessage(MessageQueue queue,Message,longuptimeMillin)方法中,插入队头,唤醒Looper,

 

二:从消息源码可以看出,它是通过一个for循环遍历是否有消息,并且会有个默认时间,第一次为0所以往下执行看是否有消息,没有消息就更改时间戳,让for循环处于阻塞状态,但是这种阻塞并不是销毁

      后面还能唤醒,而延迟加载也是这个意思,设置一个时间,当经过这么长时间后,唤醒从新遍历是否有消息。

三:ThreadLocal

    ThreadLocal提供了线程独有的局部变量存储的能力,可以整个线程存活的过程中随时随地的取用

   1. 但是ThreadLocal仅仅是简化了存取工作,并不具备线程安全,比如开启多个线程操作它,会发现并不具备线程安全

   2.它的数据类型,每一个线程对应一个ThreadLocalThreadMap对象,本质是一个数组实现的散列map

   3.每个元素都是Entry对象,key=threadLocal,value为任意值

public T get() {
    Thread t = Thread.currentThread();//当前的线程
    ThreadLocalMap map = getMap(t);通过当前的线程来获取ThreadLocalMap 
    if (map != null) {
       ThreadLocalMap.Entry e = map.getEntry(this);通过线程ThreadLocalMap 来获取队列Entry 
       if (e != null) {
        @SuppressWarnings("unchecked")
        T result = (T)e.value;
            return result;
        }
     }
   return setInitialValue();
}

 

1.通过查看Handler的源码可以清晰的看到,在Handler的构造方法中,直接通过Looper.myLooper来获取到了轮训器,从这方法我们也不难看出消息队列也是在这里获取到的mLooper.mQueue

  public Handler(@Nullable Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

2.继续往下查找可以发现Looper.myLooper是直接通过ThreadLocal来获取Looper的实例的,所以可以看出ThreadLocal的基本作用

public static @Nullable Looper myLooper() {
     return sThreadLocal.get();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值