handler 线程,android thread handler
Android的UI是单线程的。为了避免拖动GUI,一些耗时的对象应该交给独立的线程来执行。如果后台的线程执行UI对象,Android会发送一个错误消息,名为CalledFromWrongThreadException。
信息排队
在单线程模式下,为了解决类似的问题,Android设计了一个消息队列(Message Queue),通过它线程可以结合Handler和Looper组件进行信息交换。下面将分别介绍:
1.消息
消息被理解为线程之间通信的信息。如果处理数据的后台线程需要更新UI,它会将消息中包含的一些数据发送给UI线程。
2.处理者
Handler handler是消息的主要处理者,负责消息的发送和消息内容的执行。后台线程通过传入的处理程序对象引用发送消息。在使用Handler的时候,需要实现这个类的handleMessage(Message)方法,就是处理这些消息的操作内容,比如更新UI。Handler通常被子类化以实现handleMessage方法。
3.信息排队
消息队列Message Queue,用于存储Handler发布的消息,以先进先出的方式执行。
每个消息队列都有一个相应的处理程序。处理程序以两种方式向消息队列发送消息:sendMessage或post。这两条消息都将被插入到消息队列的末尾,并以先进先出的方式执行。不过这两种方法发送的消息执行方式略有不同:sendMessage发送的是一个message对象,会被Handler的handleMessage()函数处理;如果通过post方法发送一个runnable对象,它将自己执行。
4.尺蠖
Looper是每个线程中消息队列的管家。Android全局没有消息队列,Android会自动为主线程(UI线程)创建一个消息队列,但是子线程中没有消息队列。所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但是调用Looper.myLooper()得到的当前线程的Looper可能为NULL。
对于使用Looper的子线程,API Doc提供了正确的使用方法:
类LooperThread扩展线程{
公共处理程序mHandler
公共无效运行(){
looper . prepare();//创建该线程的循环,并创建MessageQueue
mHandler=new Handler() {
公共void handleMessage(Message msg) {
//在此处理传入的消息
looper . loop();//开始运行Looper并监听消息队列
}
该消息机制的一般流程:
1.Looper.loop()方法开始运行后,消息队列中的非空消息按照接收顺序循环取出。
2.首先,消息队列中的所有消息都为空。当Handler.sendMessage(Message)进入消息队列时,该函数将该消息对象的target属性设置为当前的Handler对象。然后Looper取出消息,调用消息的目标指向的Hander的dispatcher消息函数对消息进行处理。
在dispatchMessage方法中,如何处理消息由用户指定。有三个判断,优先级从高到低:
1)消息中的回调,一个实现Runnable接口的对象,其中run函数进行处理;
2)实现处理程序中mCallback所指向的回调接口的对象由其handleMessage处理;
3)处理消息的Handler对象对应的类继承并实现了handleMessage函数,通过这个实现的handleMessage函数处理消息。
所以我们实现的handleMessage方法优先级最低!
3.处理程序处理完消息后(更新UI),Looper将消息设置为NULL以便回收!