1. 概述
组成部分
- Message:消息,在线程之间传递消息
- MessageQueue:消息队列,用于存放所有通过handler发送的消息,这部分消息会一直存在于消息队列中,等待被处理。每个线程只有一个MessageQueue对象。
- Handler:处理者,用于发送和处理消息,分别对应sendMessage()和handleMessage()
- Looper:是每个线程中MessageQueue的管家,调用Looper的loop()方法后,就会进入无线循环中,每当发现MessageQueue中存在一条消息,就将它取出并传递到Handler的handleMessage()方法中。每个线程只有一个Looper对象。
2. 特别说明
Handler对象实例化的位置
Handler handler=new Handler();// 默认用当前线程的Looper
Handler handler=new Handler(Looper.getMainLooper());// 表示将消息放到主线程Looper中处理
Handler不一定要在主线程中实例化,可以在其他线程中实例化,可以使用UI线程的Looper,也可使用其他线程的Looper。实例化handler的方法:
- 若要刷新UI,Handler要用到主线程的Looper:
- 在主线程中时:
Handler handler=new Handler();
- 在子线程中时:
Handler handler=new Handler(Looper.getMainLooper());
- 若不用刷新UI,只是处理消息:
- 在主线程中时:
Handler handler=new Handler();
- 在子线程中时:
Lopper.prepare();// 因为UI线程默认调用过Looper.prepare()和Lopper.loop(),其他线程需要手动调用这两个,否则会报错
Handler handler=new Handler();
Looper.loop();
或者
Hanlder handler=new Handler(Looper.getMainLooper());
Handler的post()和sendMessage()方法
- post()和sendMessage()功能其实差不多,post也是通过sendMessage来实现的,都是发送消息到Handler所在线程的消息队列中
- post用法更方便,经常会post一个Runnable函数,处理的代码直接写在Runnable的run方法中。其实就是将这个Runnable发送到Handler所在线程(一般是主线程)的消息队列中。消息处理一般写在handleMessage()中。
public class NewsPresenterImpl implements NewsPresenter {
// presenter中持有View引用
private NewsView newsView;
// presenter中持有model引用
private NewsModel newsModel;
//
private Handler handler;
public NewsPresenterImpl(NewsView newsView) {
this.newsView = newsView;
// 在构造函数中初始化变量
newsModel = new NewsModelImpl();
// 表示该handler要用主线程的Looper,将消息发送到主线程的MessageQueue中处理消息
handler = new Handler(Looper.getMainLooper());
}
// 请求新闻数据
@Override
public void requestNewsData() {
// 当数据请求完成后的回调方法
newsView.showProgress();
newsModel.getNewsData(new OnReqNewsDataFinishedListener() {
@Override
public void onSuccess(final ArrayList<String> data) {
/*
onSucces()方法是处理数据的子线程处理完数据后回调的方法,所以onSuccess()是在子线程运行的,
故在该房中更新UI时要用handler
*/
handler.post(new Runnable() {
@Override
public void run() {
if (newsView != null) {
newsView.hideProgress();
newsView.setListItems(data);
}
}
});
}
@Override
public void onFailed() {
handler.post(new Runnable() {
@Override
public void run() {
if (newsView != null) {
newsView.hideProgress();
newsView.showMessage("请求错误");
}
}
});
}
});
}
@Override
public void onDestroy() {
newsView = null;
}
}
3.参考文献
第一行代码(第2版)_郭霖
Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别
Android中Handler的post和sendMessage的区别