一. Handler机制的四件套:
Message、MessageQueue、Looper、Handler
1.Message
消息类,存消息。通常用来更新UI。
2.MesageQueue
存放Message的消息队列,底层实现:将Message以链表形式串联起来。
主要方法:
queue.enqueueMessage(msg):将Message入队
queue.next() :从队头取走Message
3.Looper
消息队列的管理者。
主要方法:
Looper.prepare()
Looper.loop():执行后从MessageQueue中无限循环取消息,队列中没消息则阻塞,有消息就唤醒。
另,主线程(UI线程)不用自己创建Looper,系统在ActivityThread的main()方法中已经封装好了。
4.Handler
消息辅助类,封装和处理Message对象。一个线程可维护多个Handler对象。
Handler.sendMessage(msg):向消息队列发送消息
Handler.handleMessage():(主线程)处理消息
二. 我对Handler的理解
Google设计Handler机制是为了解决 在非UI线程中更新UI比较麻烦 的问题。
在子线程(工作线程)执行完耗时操作后,子线程调用主线程(UI线程)中Handler.sendXxxx(),将Message对象(一般为更新UI)送入MessageQueue。主线程不断循环从队头取消息,调用Handler.dispatchMessage() 分发消息给各Handler对象。主线程中各Handler对象调用 Handler.handleMessage() 更新UI。
三. 小demo:非UI线程做完耗时操作后更新UI
public class Activity extends android.app.Activity {
private TextView textView;
private Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what){
case 1111:
textView.setText("Has changed...");//主线程中更新UI
break;
default:
break;
}
System.out.println(msg.what);
}
};
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.activity_main);
//在子线程中执行完耗时操作,用Handler机制更新UI
new Thread(new Runnable() {
@Override
public void run() {
...耗时操作
Message msg = new Message();
msg.what = 1111; //Message的标签,用以区分Message
myHandler.sendMessage(msg);//调用主线程Handler对象,将msg加入消息队列
}
}).start();
}
}
四. 子线程创建Handler
需要重写子线程run()方法。先Looper.prepare(),再new Handler对象,最后Looper.loop()。
五. HandlerThread
HandlerThread 是一个封装了Handler和Looper的Thread,它可以执行多个耗时操作,却不需要每次都开启一个新线程。
Q:Why HandlerThread?
A:假设程序需要多次【开启子线程做耗时操作】,使用Handler机制需要不断开启、销毁线程;如果是在非UI线程中开启子线程做耗时操作(四 子线程创建Handler),还需重写非UI线程中run()方法,其中自己写Looper的prepare和loop.
使用HandlerThread,直接.start()即可,run()中已经封装好了Looper.prepare()、Looper.loop()
一个demo,参考最后第二个链接:
public class Activity extends android.app.Activity {
private TextView textView;
Handler mainHandler = new Handler();//主线程
private HandlerThread handlerThread; //HandlerThread
private Handler workHandler;//工作线程
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.tv);
handlerThread = new HandlerThread("handlerThreadName");
handlerThread.start();
//创建工作线程,
workHandler = new Handler(myHandlerThread.getLooper()){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 1:
// 通过主线程Handler.post方法进行在主线程的UI更新操作
...耗时操作
mainHandler.post(new Runnable() {
@Override
public void run () {
text.setText("UI更新了");
}
}
break;
default:
break;
}
}
}
//使用工作线程向工作线程的消息队列发送消息
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = Message.obtain();
msg.what = 1; //消息的标识
workHandler.sendMessage(msg); //通过Handler发送消息到其绑定的消息队列
}
});
}
}
参考资料:
Android校招面试指南:Android消息机制
Handler、Thread、HandlerThread三者的区别
HandlerThread 详解