Android-Handle(线程间通信)详解
线程间通信是在Android开发中比较经常遇到的,我们刷新UI界面一般是通过子线程做完某些事情后,要改变主页面就要通过数据的通信,让主线程接收到信息后自己改变UI界面。
线程间通信相关的类
1.Handle
先进先出原则;
2.Looper
类用来管理特定线程内对象之间的消息交换(MessageExchange);
3.Message
类用来保存数据。
线程通信的过程
1.Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列);
2.Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息;
- Message Queue(消息队列):用来存放线程放入的消息;
4.线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue;
消息类——Message
android.os.Message的主要功能是进行消息的封装,同时可以指定消息的操作形式,Message类定义的变量和常用方法如下:
- public int what:变量,用于定义此Message属于何种操作;
- public Object obj:变量,用于定义此Message传递的信息数据,通过它传递信息;
- public int arg1:变量,传递一些整型数据时使用;
- public int arg2:变量,传递一些整型数据时使用;
- public Handler getTarget():普通方法,取得操作此消息的Handler对象。
在整个消息处理机制中,message又叫task,封装了任务携带的信息和处理该任务的handler。message的用法比较简单,但是有这么几点需要注意:
- 尽管Message有public的默认构造方法,但是你应该通过Message.obtain()来从消息池中获得空消息对象,以节省资源;
- 如果你的message只需要携带简单的int信息,请优先使用Message.arg1和Message.arg2来传递信息,这比用Bundle更省内存;
- 擅用message.what来标识信息,以便用不同方式处理message。
消息通道类——Looper
在使用Handler处理Message时,需要Looper(通道)来完成。在一个Activity中,系统会自动帮用户启动Looper对象,而在一个用户自定义的类中,则需要用户手工调用Looper类中的方法,然后才可以正常启动Looper对象。Looper的字面意思是“循环者”,它被设计用来使一个普通线程变成Looper线程。所谓Looper线程就是循环工作的线程。在程序开发中(尤其是GUI开发中),我们经常会需要一个线程不断循环,一旦有新任务则执行,执行完继续等待下一个任务,这就是Looper线程。使用Looper类创建Looper线程很简单:
public class LooperThread extends Thread {
@Override
public void run() {//将当前线程初始化为Looper线程
Looper.prepare(); // ...其他处理,如实例化handler
// 开始循环处理消息队列
Looper.loop();
}
}
这是在子线程中创建Handler的情况,如果在主线程中创建Handler是不需要调用Looper.prepare();
和 Looper.loop();
方法。
Looper的特点:
- 每个线程有且只能有一个Looper对象,它是一个ThreadLocal ;
- Looper内部有一个消息队列,loop()方法调用后线程开始不断从队列中取出消息执行;
- Looper使一个线程变成Looper线程。
消息操作类——Handle
Handle的定义
Handler是更新UI界面的机制,也是消息处理的机制。我们可以通过Handle发送消息,也可以处理消息。
使用Handle的原因
Android在设计的时候,封装了一套消息创建、传递、处理机制,如果不遵循这样的机制就没有办法更新UI信息,就会抛出异常。
创建Handler实例化对象时,可以重写的回调方法:
void handlerMessage(Message msg);
常用方法
post(Runnable)
postAtTime(Runnable, long)
postDelayed(Runnable, long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message, long)
sendMessageDelayed(Message, long)
总结
Handle的主要作用
- 在子线程中发送数据;
- 在主线程中接收数据,处理数据。
Handle创建和使用的简化过程
- 在主线程创建Handle对象,重写handleMessage(msg)方法,用来随时接收数据;
- 在子线程调用主线程创建的Handle对象,来给主线程发送消息;
- 主线程接收到子线程发送来的消息,进行处理,可以直接显示在UI界面上。