zoukankan      html  css  js  c++  java
  • Android线程Handler的学习

    Android的UI是单线程(Single-threaded)的。为了避免拖住GUI,一些较费时的对象应该交给独立的线程去执行。如果幕后的线程来执行UI对象,Android就会发出错误讯息 CalledFromWrongThreadException

    Message Queue

         在单线程模型下,为了解决类似的问题,Android设计了一个Message Queue(消息队列), 线程间可以通过该Message Queue并结合Handler和Looper组件进行信息交换。下面将对它们进行分别介绍:

     

    1. Message
        Message消息,理解为线程间交流的信息,处理数据后台线程需要更新UI,则发送Message内含一些数据给UI线程。
     
    2. Handler
        Handler处理者,是Message的主要处理者,负责Message的发送,Message内容的执行处理。后台线程就是通过传进来的Handler对象引用来 sendMes sage(Message) 。而使用Handler,需要implement 该类的   handleMessage(Message) 方法,它是处理这些Message的操作内容,例如Update UI。通常需要子类化Handler来实现handleMessage方法。
     
    3. Message Queue
        Message Queue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
        每个message queue都会有一个对应的Handler。Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。
     
    4. Looper
        Looper是每条线程里的Message Queue的管家。Android没有Global的Message Queue,而Android会自动替主线程(UI线程)建立Message Queue,但在子线程里并没有建立Message Queue。所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但调用Looper.myLooper()得到当前线程的Looper就有可能为NULL。

        对于子线程使用Looper,API Doc提供了正确的使用方法:

    class LooperThread extends Thread { 
        public Handler mHandler; 
     
        public void run() { 
            Looper.prepare(); //创建本线程的Looper并创建一个MessageQueue
     
            mHandler = new Handler() { 
                public void handleMessage(Message msg) { 
                    // process incoming messages here 
                } 
            }; 
       
            Looper.loop(); //开始运行Looper,监听Message Queue 
        } 
    } 


    这个Message机制的大概流程:

        1. 在Looper.loop()方法运行开始后,循环地按照接收顺序取出Message Queue里面的非NULL的Message。

        2. 一开始Message Queue里面的Message都是NULL的。当Handler.sendMessage(Message)到Message Queue,该函数里面设置了那个Message对象的target属性是当前的Handler对象。随后Looper取出了那个Message,则调用该Message的target指向的Hander的dispatchMessage函数对Message进行处理。

        在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:

        1) Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;

        2) Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;

        3) 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。

        由此可见,我们实现的handleMessage方法是优先级最低的!

        3. Handler处理完该Message (update UI) 后,Looper则设置该Message为NULL,以便回收!


  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3024927.html
Copyright © 2011-2022 走看看