amp@java

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  99 随笔 :: 0 文章 :: 228 评论 :: 0 Trackbacks
这是mars课程里面关于handler和线程的一个例子:
package mars.handler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;

public class HandlerTest extends Activity {
    Handler handler 
= new Handler();
    
/** Called when the activity is first created. */
    @Override
    
public void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        System.out.println(
"1");
        handler.post(r);
        System.out.println(
"2");
        setContentView(R.layout.main);
        System.out.println(
"activity---->"+Thread.currentThread().getId());
        System.out.println(
"activity name--->"+Thread.currentThread().getName());
    }
    
    Runnable r 
= new Runnable() {
        
        @Override
        
public void run() {
            
// TODO Auto-generated method stub
            System.out.println("handler---->"+Thread.currentThread().getId());
            System.out.println(
"handlername---->"+Thread.currentThread().getName());
            
try {
                Thread.sleep(
10000);
            } 
catch (InterruptedException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(
"3");
        }
    };
}

根据mars的解释,handler所在的线程跟Activity的线程是同一个线程,所以在
handler.post(r);
语句后,执行的是Runnable里面的run函数,这个函数没有在新开的线程中执行,只是简单地调用了run函数,所以这个app在模拟器运行时要过10秒才会显示界面,因为run函数里面睡眠了10秒,等它返回后才执行setContentView函数设置界面元素。
根据实际运行结果,的确是过了10秒才能显示界面。

但是奇怪的是System.out语句似乎没有受到影响,下面是日志:
log
02-09 11:12:43.553: INFO/System.out(591): 1
02-09 11:12:43.553: INFO/System.out(591): 2
02-09 11:12:43.674: INFO/System.out(591): activity---->1
02-09 11:12:43.674: INFO/System.out(591): activity name--->main
02-09 11:12:43.713: INFO/System.out(591): handler---->1
02-09 11:12:43.713: INFO/System.out(591): handlername---->main
02-09 11:12:53.775: INFO/System.out(591): 3

从日志可以看出,除了run函数里面睡眠后才执行的打印函数推迟了10秒才执行之外,其他都是没有受到任何延时,顺序执行的,在
handler.post(r);
语句前后的打印函数都被按顺序执行了,唯独
setContentView(R.layout.main);
需要在run函数返回后才执行,这是什么道理?难道打印函数的优先级更高,不会堵塞?如果是这样的话为什么在run函数里面还是要等睡眠结束才执行呢?
posted on 2012-02-09 19:25 amp@java 阅读(1735) 评论(6)  编辑  收藏

评论

# re: Activity里一个奇怪的执行顺序 2012-02-09 20:21 dzwillpower
这个问题我也觉得很奇怪,为什么没有人回答呢,求高手解答啊  回复  更多评论
  

# re: Activity里一个奇怪的执行顺序 2012-02-10 10:11 小权
handler.post(r);
是将runnable对象post到主线程消息队列的队尾,等主线程取出这个消息对象的时候才会执行这个runnable中的run方法。

这样就是你为什么看到最后执行run方法的原因。

API:
public final boolean post (Runnable r)

Since: API Level 1
Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.  回复  更多评论
  

# re: Activity里一个奇怪的执行顺序 2012-02-10 10:29 amp@java
@小权
但是这两句:
setContentView(R.layout.main);
System.out.println("activity---->"+Thread.currentThread().getId());
都是在
handler.post(r);
后面,实际效果却是后面那句比前面那句先执行,是不是
setContentView
实际上也是放到消息队列里,马上返回但并没有立即执行的原因?
  回复  更多评论
  

# re: Java编程打开运行exe程序 2012-02-11 11:06 tb
恩不错呀!  回复  更多评论
  

# re: Activity里一个奇怪的执行顺序 2012-03-09 17:15 futurexiong
今天群里的一个人拿着你这贴子问了问题,所以,我在这里回复一下吧。由于Activity的显示是在onResume之后,所以给你的感觉是setContentView并没有执行,实际上这个方法并不是显示界面,你把概念搞混了。实际上这个方法在run方法之前已经执行了。mars的解释是有问题的。如果你不相信,在setContentView下面使用findViewById方法把TextView拿到并打印出TextView的内容,看看是否执行了。生命周期一定要搞清楚。  回复  更多评论
  

# re: Activity里一个奇怪的执行顺序 2012-03-15 09:42 amp@java
@futurexiong
是不是说run方法是在onCreate和onResume之间执行的呢?  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: