zoukankan      html  css  js  c++  java
  • Android开发艺术探索学习笔记(十)

    第十章  Android的消息机制

         面试中经常会被问到的一个问题:handler是如何在子线程和主线程中进行消息的传递的,这个问题通过了解Android的消息机制可以得到一个准确的答案。

        Android的消息机制主要就是指Handler的运行机制,Handler的运行需要底层的MessageQueue和Looper的支撑。需要理解两个概念:

        MessageQueue:消息队列,通过单链表的数据结构来存储一组消息,以队列的形式对外提供插入和删除的工作。

        Looper:消息循环,以无限循环的方式查找MessageQueue是否有新消息,有的话就处理消息,否则一直等待。

        如果需要使用Handler就必须为Handler所在的线程创建Looper,主线程在创建的时候会自动初始化Looper,而子线程默认是没有Looper的,这就是在主线程默认可以使用Handler而子线程中默认不能使用Handler的原因。

        Android系统之所以提供Handler,主要就是为了解决在子线程中无法访问UI的矛盾。之所以不允许在子线程中访问UI,主要是考虑到控件不是线程安全的,因为多个线程访问控件可能会导致UI控件处于不可预期的状态。

        Handler,MessageQueue,Looper的工作工程如下图所示:

        

        首先Handler通过post方法将一个Runnable或者send方法将一个消息投递到handler内部的Looper中,其实post方法最后也是通过send方法来完成的,所以以send方法为例,当send方法被调用后,它会调用MessageQueue中的enqueueMessage方法将这个消息放入MessageQueue中,此时looper发现MessageQueue中存在新消息,会开始处理这个消息,最终Handler中的handleMessage方法就会被调用,因为Looper是运行在创建Handler所在的线程中,这样一来就完成了消息在子线程和主线程中的传递。

        MessageQueue主要包含两个操作,插入(enqueueMessage)和读取(next),读取本身会伴随这删除操作。enqueueMessage方法的作用是往消息队列中插入一条消息,next方法的作用是从消息队列中取出一条消息并将其从消息队列中移除。

        Looper的主要作用就是不断的从MessageQueue查看是否有新消息,如果没有就一直阻塞在那里。

         子线程中如果需要使用Handler那就必须先为子线程创建一个Looper,通过Looper.preper()可以为当前线程创建一个 Looper,然后通过Looper.loop()来开启消息循环,当使用完毕后需要调用Looper.quit()来终止消息循环,否则由于 Looper内部是一个死循环导致子线程会一直处于等待的状态,也就是线程不能结束。

        

          

  • 相关阅读:
    在VS2010下,用QT,创建一个Opencv应用程序
    SNR(信噪比)与 特定分布噪声的关系初探
    Qt学习笔记_FindDialog
    关于reduced rank regression的一些看法
    实时摄像头人眼跟踪: RealTime Tracking Of Human Eyes Using a Webcam
    L1_APG_Tracker实现代码剖析
    CVPR2013 感兴趣论文汇总
    使用PowerDesigner 15对现有数据库进行反向工程(图解教程)(转)
    大数据量高并发的数据库优化
    rtmp和rtsp的区别
  • 原文地址:https://www.cnblogs.com/shiwei-bai/p/5129500.html
Copyright © 2011-2022 走看看