当前位置:编程学习 > wap >>

在oncreate()方法中handler的post先执行再显示界面?why

package test1.test.run;

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

public class Main extends Activity {

private Runnable run = new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Handler handler = new Handler();
handler.post(run);

setContentView(R.layout.main);
Log.v("!", "end");
}
} --------------------编程问答-------------------- 请从源代码的方面来解释,感谢 --------------------编程问答-------------------- setContentView(R.layout.main);
Handler handler = new Handler();
handler.post(run);

--------------------编程问答-------------------- 你在主线程执行啊
肯定先走handler再显示画面 --------------------编程问答-------------------- hanlder.post()是在主线程执行的 --------------------编程问答-------------------- 楼上前辈我知道是在主线程中执行的,为什么先打印后显示界面呢 --------------------编程问答-------------------- 不会吧,CSDN就这水准 ?还是高手们不屑 --------------------编程问答-------------------- 谁来解释下这个问题,我也是比较困惑啊??? --------------------编程问答-------------------- --------------------编程问答-------------------- 我今天在看post方法的时候也遇到了这个问题,跟朋友讨论了很久,我们推理出来的结论是这样的,不知道是不是对的。也希望楼下的朋友们给些看法。
    推理:
    在运行虚拟android手机环境的时候,是要先显示出来页面的,与你的post方法放在onCreate()方法中的哪里是无关。我们在往主线程里coding的时候就主要注意避免假死现象的出现,如果你加载一个信息的时间过长,就会强制退出,所以加载大一些的图片,甚至是视频的时候都不用主线程去操作,而是选择用多线程异步加载。
    同样的,不管你的主线程sleep的时间有多长,当然时间过长也同样出现强行关闭页面。所以,极有可能可能是android内部设定的一些机制导致的,一旦程序运行成功,就先加载页面。也就是说从一开始你的UI线程(主线程)已经在执行了。
    Looper也有这样一种机制,就是“先进先出”,一旦你的UI更新完初始化之后,才再执行这个post的方法,所以,我们也在考虑,是不是无论怎样的操作主线程,post都会被放到Looper序列的最后去执行。
    以上仅代表个人的一些看法,不确定是否正确。 --------------------编程问答-------------------- 看来楼主对acticity的生命周期还不是很理解
一个acticity会经历onCreate(初始化工作)-->onStart(开始显示界面,但用户对界面不能操作)-->onResume(界面显示完成,用户可以操作界面),然后再是其他的
由此可见,只有程序走到onResume时,才算是界面显示
所以你在onCreate里面的输出肯定是在界面显示之前的(并不是说setContentView(R.layout.main)就是显示界面,这只是初始化工作)
至于post为什么先于显示界面,程序是由上而下执行的,你的post方法在onCreate里面调用,自然是先于显示界面的
不知道这样解释,你能明白不? --------------------编程问答-------------------- 其实,10楼的朋友,你把post放在setContentView(R.layout.main)下面还是一样的结果,并不是因为程序是由上而下执行 这个原因导致的。 --------------------编程问答--------------------
引用 11 楼 qq529895481 的回复:
其实,10楼的朋友,你把post放在setContentView(R.layout.main)下面还是一样的结果,并不是因为程序是由上而下执行 这个原因导致的。

....晕倒
post方法在onCreate里面调用的,而onCreate是先于onResume(显示界面)执行的,所以post自然先于显示界面了 --------------------编程问答--------------------
引用 11 楼 qq529895481 的回复:
其实,10楼的朋友,你把post放在setContentView(R.layout.main)下面还是一样的结果,并不是因为程序是由上而下执行 这个原因导致的。

可能这一点我描述的不是很清楚 --------------------编程问答-------------------- handler.post 是在UI主线程中的

安卓群222164346,欢迎加入,谢谢!


--------------------编程问答-------------------- 主线程收到消息了就执行。你先于onResume()发消息了,所以先处理这个消息。所以不是说自上而下执行,毕竟这是多任务、多线程系统。准确说,是同一个线程中,消息也是有顺序的,先入先出。但,如果你干的事情在不同线程中,就再另外说。 --------------------编程问答--------------------
引用 12 楼 fengli3863 的回复:
引用 11 楼 qq529895481 的回复:
其实,10楼的朋友,你把post放在setContentView(R.layout.main)下面还是一样的结果,并不是因为程序是由上而下执行 这个原因导致的。

....晕倒
post方法在onCreate里面调用的,而onCreate是先于onResume(显示界面)执行的,所以post自然先于显示界面了


这样,我再说一下我想要表达的问题。

post是在onCreate里面执行的没有错,楼主的程序
    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         Handler handler = new Handler();
         handler.post(run);(post方法)

         setContentView(R.layout.main);
         Log.v("!", "end");(Log打印)
       }
    


的主界面也会在休眠两秒以后出现,但是问题就来了,既然,休眠两秒以后才出现主界面,也就是说那个程序中的Log原本也是应该在两秒以后才出现的,而不是立刻就出现在LogCat中的。不知道,这回是不是表达清楚了。 --------------------编程问答-------------------- 呵呵,感谢楼上几位朋友的讨论,我这是这么认为的,由于此post代码是放在activity的oncreate阶段运行的,所以activity还并没有显示出来,这时android系统认为还有一些初始化的东西未执行完,比如队列中的runnable对象,当把这些队列中的资源全执行完成后,才显示activity界面,这样显示给用户是最终的界面,并不会发生像异步那样突然改变ui的情况,

当然这段代码如果在button的on click中实现post后更改textview的text时又和放在on create中的情况又不一样, --------------------编程问答-------------------- onCreate onPause onResume以及handler post的runnable,还有keyevent,touchEvent 都是一个一个代码片段,执行实际上是由主线程来调度的,【也就是回调函数机制】。 
如果在onCreate中就post出去,那是极有可能在onResume之前就被执行。
如果在onCreate中,不是用post方法,用postDelayed方法,

handler.postDelayed(run, 5000);

则应该会在界面显示完成后执行的, 界面的render和显示应该要不了5秒。 --------------------编程问答-------------------- 到底其实就是activity生命周期的问题。如10楼所说 --------------------编程问答-------------------- 这个问题是值得学习的!可以更好地理解activity的生命周期 --------------------编程问答-------------------- 嗯,明白mHandler.post()在UI线程,然后就是Activity的生命周期都明白了。 --------------------编程问答-------------------- 这个问题的关键是post将runnable对象放在消息队列的哪个地方,因为主线程也是消息驱动的。在onCreate里边调用post只是将runnable加入到消息队列中,onCreate还需继续执行完成。然后主线程在从队列中获取下一个执行消息(对象)。所以Log.v("!", "end")先执行很正常。 

接下来就要看下一个消息是谁了, 是post上去的runnable对象,还是显示消息呢 (可能还有其他的消息,我们只考虑相关的这两个)。 从楼主运行的结果来看,post上去的runnable对象是在显示之前的。
--------------------编程问答--------------------
引用 22 楼 dairyman000 的回复:
这个问题的关键是post将runnable对象放在消息队列的哪个地方,因为主线程也是消息驱动的。在onCreate里边调用post只是将runnable加入到消息队列中,onCreate还需继续执行完成。然后主线程在从队列中获取下一个执行消息(对象)。所以Log.v("!", "end")先执行很正常。 

接下来就要看下一个消息是谁了, 是post上去的runnable对象,还是显示消息呢……


这个理解很正确!受教了! --------------------编程问答-------------------- 顶!顶!顶!顶!
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,