问题描述:
Android中Handler.post可以用来修改UI布局,关于Handler机制可以参看我的另一篇博客《Handler详解》。handler.post(Runnable r)方法是将Runnable对象发送到主线程中执行,并且源码注释如下
* Causes the Runnable r to be added to the message queue.注释的意思是runnable会在handler所在的线程中执行。按照注释的意思以及我们经常使用的情况来看,runnable的逻辑无疑是在主线程中执行的。不过我们还是来验证一下。
* The runnable will be run on the thread to which this handler is
* attached.
过程分析
首先打印出了主线程的线程ID,然后直接在主线程中执行了runnable的run方法,又new了两个Thread同时打印出了对应的线程ID。
public class ThreadTest {
public static void main(String args[]){
System.out.println("thread id = " + Thread.currentThread().getId());
new MyRunnable().run();
new MyRunnable().run();
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
}
public static class MyRunnable implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("runnable thread id = " + Thread.currentThread().getId());
}
}
}
运行结果:
thread id = 1
runnable thread id = 1
runnable thread id = 1
runnable thread id = 10
runnable thread id = 11
结论:
从运行结果中可以看出主线程的线程ID为1,在主线程中运行两次Runnable,其中打印出的ID也是1,在主线程中运行Thread,打印出的线程ID为10,11。
所以说runnable.run()方法逻辑的执行际上是在runnable所在的线程中的执行的,runnable并不会新开辟一个子线程。runnable中的逻辑实际上是在主线程中执行的,要是runnable逻辑出现阻塞,那么主线程也会相应的被阻塞。而Thread就是完全开辟了一个子线程了,线程ID发生了变化。
回到开头提到的问题,handler.post方法可以进行UI修改,但是里面的逻辑是在主线程中执行的,要是有耗时操作,会阻塞主线程,导致点击事件无响应等,所以handler.post可以用作修改UI,但是不应该用Handler.post执行一些复杂的逻辑。