Android的消息机制

     Android的消息机制主要是指Handler的运行机制,而Handler的运行离不开MessageQueue和Looper的支撑。 其中MessageQueue称为消息队列,用作存储一组消息,并以队列的形式对外提供插入和删除工作 (具体实现:使用单链表的结构来存储消息列表)。 MessageQueue不能处理消息 Looper称为循环,会以无限循环方式去查找消息和处理消息。
     如何获取当前线程的Looper( 创建Handler对象时需要当前线程Looper来构造消息系统循环 )?通过ThreadLocal可获取每个线程的Looper(ThreadLocal在不同的线程中互不干扰的存储和提供数据)。
一、Android的消息机制概述
     1)Handler主要作用: 将一个任务切换到某个指定的线程中执行;
     2)子线程不能访问UI原因:
         A)子线程访问UI,会抛出异常; 原因是ViewRootImpl对UI操作左了验证和限制---->UI只能由Android主线程访问。
         B)UI控件不是线程安全的; 不加锁原因:防止UI逻辑复杂以及UI访问效率低。
     3)Handler的工作过程:A)当send方法调用时,会调用MessageQueue的enqueueMessage方法将消息放入消息队列中;B)然后 Looper发现有新的消息就会处理这个消息 ,最终消息中的Runnable或者handleMessage方法被调用。 注意:处理消息是在创建Handler所在线程中。

二、ThreadLocal的工作原理
     ThreadLocal是一个线程内部的数据存储类, 通过它可以在指定的线程中存储数据,数据存储后, 只有在指定线程中可以获取到存储数据 ,对于其他线程是无法获取的。eg:

     在主线程设置mBooleanThreadLocal为true;在子线程1设置其为false;在子线程2不设置,然后通过 同一个mBooleanThreadLocal的get方法 获取值, 然而3个线程中mBooleanThreadLocal的值不一样。
     原因:不同线程访问同一个ThreadLocal的get方法, ThreadLocal内部会从各自线程的中取出一个数组 (每个线程内数组不同) ,然后再从数组中根据当前ThreadLocal的索引去查找对应的value值。
2.1 ThreadLocal的set方法
    
1)首先先通过values方法获取当前线程的TheadLocal数据;如何获取?在Thread类的内部有一成员专门 用于存储线程的ThreadLocal数据 :ThreadLocal.Values  localValues;
     2)在localValues内部有一数组:Object[] tables,ThreadLocal的值就是存放在tables数组中。也即通过 localValues的put方法将value值存储到数组中:
2.2 ThreadLocal的get方法
    
1)第一步,同样是取出当前线程的localValues对象;如果对象为null,直接返回初始值;
     2)如果对象不为null,从localValues对象中取出table数组,并从数组中获取value。
     总结: 从上面set和get源代码可以看出,它们的操作对象都是当前线程的localValues对象的table数组,导致在不同线程中访问同一个ThreadLocal对象的set和get方法,它们对ThreadLocal所做的读/写操作仅限于各自线程的内部。
三、消息队列的工作原理
     Android中消息队列是指MessageQueue。MessageQueue主要包含两个操作:插入和读取。
     1)插入: 由enqueueMessage方法完成; 往消息队列中插入一条消息;单链表的插入
     2)读取: 由next方法完成; 从消息队列中取出一条消息并将其从消息队列中删除。如果消息队列中没有消息,next方法会阻塞,当新消息到来时,next方法会返回这条消息并将其从单链表中删除。
四、Looper的工作原理
     不停从MessageQueue中查看是否有新的信息,如果有新的信息就会立刻处理 ,否则就一直阻塞。
4.1 Looper的构造函数

1)创建一个MessageQueue消息队列;
2)将当前线程对象保存下来;
4.2 为线程创建Looper对象
     1)通过Looper.prepare()即可为当前线程创建一个Looper对象;
     2)通过Looper.loop()来开启消息循环;
3)getMainLooper()方法可以在任何地方获取到主线程的Looper。
五、Handler的工作原理
Handler的工作主要包含: 消息的发送和接收过程 。1)消息的发送是通过post方法以及 send一系列方法完成的。
5.1 消息的发送
源代码如下:
1) Handler发送消息的过程 向消息队列中插入一条消息,MessageQueue的next方法就会返回消息给Looper;
2) Looper收到消息就开始处理 ,最终 消息由Looper交给Handler处理 ,也即 Handler的dispatchMessage方法被调用。
5.2 消息的处理
1)首先, 检查Message的callback是否为null,不为null就通过handleCallback来处理消息 ;Message的Callback是一个Runnable对象(post方法所传递的Runnable参数)
2)其次 ,检查mCallback是否为null,不为null就调用mCallback的handleMessage方法来处理消息。 其中 Callback是个接口 ,其接口方法需要在子类实现。
3)最后, 调用Handler的handleMessage方法来处理消息 。其流程如下:
5.3 Handler的构造函数
1)通过特定的Looper来构造Handler:
2)通过默认构造方法:











    
    
    
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值