下面我们就来讲解Handler的简单使用,我们实现一个模拟下载过程的操作,并将下载进度更新到进度条和TextView中,那么事不宜迟,我们马上开始。
我们先来总结下使用Handler的步骤:
- 创建Hanlder对象,并在handleMessage方法中完成逻辑代码
- 创建子线程,在子线程中创建Message对象,使用handler.post方法将消息发送给消息队列(MessageQueue)
- handler收到消息,并调用handleMessage方法完成通信(本质上是Looper轮询从MessageQueue中取出消息,并将其发送给Message的target,也就是发送给了handler)
创建Handler对象
上代码:
/**
* 第一步,主线程中创建Handler并在handleMessage方法中处理相应逻辑
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//这里完成更新UI的操作
//do something
}
};
Handler的创建还有其他的方法,比如传入一个Callback对象的构造方法等等,不一而论, 这里handleMessage方法主要是用来处理子线程中传递出来的消息
创建子线程
Android中创建子线程的方法有很多,我这里使用了一种最常见的方法:
//创建子线程
downloadThread = new Thread(new Runnable() {
@Override
public void run() {
//线程结束标志,activity销毁后不再执行线程内代码
if(!destroyThread) {
//do something
for(int i = 0;i < 100;i++) {
progress++;
//模拟耗时操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = Message.obtain();
message.what = MESSAGE_WHAT_UPDATE_PROGRESS;
message.obj = progress;
handler.sendMessage(message);
}
}
}
});
可以看到上述代码中,主要是模拟了耗时操作,每100ms发出一次消息,消息体中what主要用于区分消息类型,obj携带消息内容,最后调用handler.sendMessage方法将其发出。其中Message的初始化有多种方式,常用的有三种:
- new Message();
- Message.obtain();
- Handler.obtainMessage();
其中我们经常使用的是后两者,而不推荐使用前者,这主要是因为,后两者是从一个可回收的对象池中获取Message对象,比重新new一个Message对象性能更好。
Handler对象处理消息
Looper取到消息后会根据Message的target对象将消息发送给相应的Handler(hander.sendMessage方法会将自身设为该Message的target),然后调用handlerMessage进行处理:
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//这里完成更新UI的操作
if(msg != null && msg.what == MESSAGE_WHAT_UPDATE_PROGRESS) {
int progress = (int) msg.obj;
String value = "";
if(progress <= MAX_PROGRESS) {
progressBar.setProgress(progress);
value += "第一进度条:"+progress+"%";
}
if(progress*2 <= MAX_PROGRESS) {
progressBar.setSecondaryProgress(progress*2);
value += " 第二进度条:"+progress*2+"%";
} else {
value += " 第二进度条:"+MAX_PROGRESS+"%";
}
tvProgressValue.setText(value);
}
}
};
整个Handler的使用流程就是这样了,下面是demo的执行画面:
模拟下载进度条demo
这里就是一个完整的Handler使用的流程了,其中涉及到了一些名词,如Message、MessageQueue、Looper等,我们会在后面详解Hanlder中进行讲解,那么这篇文章就到这里,接下来敬请期待~