简介
Handler提供的种异步消息处理机制是:当它发出一个消息进入消息队列后,发送消息的函数立刻返回,接着主线程会逐个地从消息队列中把消息取出,然后对消息进行处理。明显,Handler发送消息和接收消息是异步进行的,Handler跟线程没有关系。
Handler可以在一个线程内部做异步的消息处理,也可以在线程之间做异步消息处理。
默认情况下,每个Handler实例都会被绑定到创建它的线程中(一般是位于主线程),即 Handler和它的调用者实际上是处于同一线程的。
示例
通过输出Activity和Handler所在线程的ID值,证明Handler和调用它的Activity是在同一个线程中的。
第一步:在主布局文件中依次提供三个onClick属性值分别为fun1、fun2、fun3的Button控件。
第二步:修改MainAcvitity类的代码如下所示:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("MainActivity " + Thread.currentThread().getId());
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("Handler " + Thread.currentThread().getId());
}
};
Runnable runnable = new Runnable() {
public void run() {
System.out.println("Runnable " + Thread.currentThread().getId());
Message msg = handler.obtainMessage();
handler.sendMessage(msg);
}
};
public void fun1(View view) { // 在一个线程的内部做异步消息处理
Message msg = handler.obtainMessage();
handler.sendMessage(msg); //发送消息到消息队列。此处参数不为null,否则报空指针
}
public void fun2(View view) { // 在一个线程的内部做异步消息处理
handler.post(runnable); // 把线程对象runnable加入到消息队列当中
}
public void fun3(View view) { // 在线程之间做异步消息处理
new Thread(runnable).start();
}
}
Handler类的sendMessage()和post()方法是将参数放到同一个消息队列中,由此可知消息队列不仅可以放Message,还可以放Runnable。
运行程序,依次单击fun1、fun2、fun3三个按钮,结果如下图所示。
分析上面程序运行结果可以得出如下结论:
- 通过fun1或fun2与fun3的比较,证明了Handler可以在一个线程内部做异步的消息处理,也可以在线程之间做异步消息处理。
- 不管是在主线程中还是在子线程中启动Handler,Handler所在的线程的id与主线程的id都相同,这证明了Handler和调用它的Activity实际上是处于同一线程的。
- 调用handler.post()方法执行Runnable对象的时候,并没有调用start()方法真正另外启动一个新的线程,而是直接在原有的线程上调用了run()方法。
- 通过new Thread(runnable).start()调用handler时, runnable位于新开启的线程当中,但handler仍在主线程中。