谷歌官网解释:http://developer.android.com/reference/android/os/Handler.html
粗浅解释:即在子线程中完成的相对耗时的工作(如读取较大的文件,联网读取数据),通过Handler实现主线程(即UI线程,Android程序启动时第一个启动的线程,即通常
的MainActivity.java文件)与子线程的数据传递,主线程通过传递来的信息进行UI的更新。
为什么耗时工作不能直接在主线程中完成?
会造成界面假死现象,若5秒还没完成当前工作,Android系统会提示“强制关闭”界面。在子线程中完成,因为子线程涉及到UI的更新,而Android要求的是只能在主线程中才能
对UI进行更新,子线程操作是危险的,会出现报错,Handler就是为了解决这个问题出现的。
Handler是运行在主线程中的(注意不是子线程),与子线程可以通过Message对象传递数据(子线程中的sendMessage()方法),Handler负责接收传递来的数据,在配合主
线程完成UI更新。
Handler特点
javadoc中,对Handler是这样解释的:Handler可以发送和处理消息对象或Runnable对象,这些消息对象和Runnable对象与一个线程相关联。每个Handler的实例都关联了
一个线程和线程的消息队列。当创建了一个Handler对象时,一个线程或消息队列同时也被创建,该Handler对象将发送和处理这些消息或Runnable对象。
(官网解释) Handler可以分发Message对象和Runnable对象到主线程中(即在主线程中创建Handler类对象),对于每个Handler实例,都会绑定到创建他的线程中(一般为主线程),他的两个主要作用:
(1):安排消息或Runnable在某个主线程中某个地方执行
(2):安排一个动作在不同的线程中执行
这里,Handler实例是如何绑定到创建他的线程中的呢?
其实这个很简单,如果你new了一个无参构造函数的Handler对象,那么这个Handler将自动与当前运行线程相关联,也就是说这个Handler将与当前运行的线程使用同一个
消息队列,并且可以处理该队列中的消息。
下面通过对当前线程ID的输出,来验证这个说法:
public class MainActivity extends Activity {
private Handler handler = new Handler(); //创建一个Handler对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("用户当前线程ID:"+Thread.currentThread().getId());
handler.post(runnable); //通过post()方法,向消息队列中推送一个Runnable对象。
}
private Runnable runnable = new Runnable() {
@Override
public void run() { //在Runnable的run方法中打印当前ID
System.out.println("Runnable线程ID:"+Thread.currentThread().getId());
}
};
输出结果: