我对android文档的阅读发现方法forceLayout()(在下一个布局请求中生成布局显示)和requestLayout()(应该发布一个即时布局请求),但是我无法得到他们表现得像宣传的那样。特别是,如果我在Thread.Sleep之前设置一个文本,然后在一个之后设置文本,它会在设置两个文本之前等待Sleep完成,无论是否在中间调用forceLayout()和requestLayout()。请不要回答很多关于我不应该在UI线程中调用Thread.Sleep的废话。如果我将Thread.Sleep包装在CountDownTimer中,它可以很好地工作(只要我有足够短的滴答时间来不干扰睡眠时间,并且定时器的持续时间足够长以允许睡眠完成。以下是一个例子:
int i=0;
TextView tv2;
TextView tv1;
LinearLayout ll;
Button bt;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ll=new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
tv1=new TextView(this);
tv2=new TextView(this);
bt=new Button(this);
bt.setText("Press to start");
ll.addView(bt);
ll.addView(tv1);
ll.addView(tv2);
tv2.setText("");
setContentView(ll);
bt.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tv1.setText("starting sleep");
new CountDownTimer(6000,50){
public void onTick(long msuf)
{if(i==1)
{
try{
Thread.sleep(4000);
tv2.setText("waking up");
}
catch(InterruptedException e){};
}
i++;
}
public void onFinish(){}}.start();
}
});
}
答案 0 :(得分:11)
[关于在UI线程中调用sleep()
的大量废话]。如果我做对了,你的意思是说:
//...inside onTick()
try {
tv2.setText("almost waking up"); // first setText()
Thread.sleep(4000);
tv2.setText("waking up"); // second seText()
}
如果你使主线程休眠,它将停止处理任何东西:当前方法,线程循环和消息队列。一旦再次唤醒,它将完成执行该方法,第二个setText()
覆盖第一个,然后让线程循环继续并进行UI刷新,仅显示第二个文本。
非requestLayout()
和forceLayout()
实际上可以立即刷新UI,它们将在线程循环中计划布局请求。我不确定,但我认为它们之间的区别在于requestLayout()
是由一个已在其父中更改其大小/位置的视图调用的,而forceLayout()
是由ViewGroup
调用,需要其子项重新布局。
因此[更多关于在UI线程中调用sleep()
的废话]。对于这样的事情,如果你不想搞乱多线程,那么在主线程处理程序上调用postDelayed()
可能是最好的解决方案。