我试图这样做
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t=new TextView(this);
t=(TextView)findViewById(R.id.TextView01);
t.setText("Step One: blast egg");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.setText("Step Two: fry egg");
但由于某种原因,我运行它时只显示第二个文本。我认为它可能与Thread.sleep()
方法阻塞有关。那么有人可以告诉我如何“异步”实现定时器吗?
感谢。
答案 0 :(得分:147)
您的onCreate()
方法有几个巨大的缺陷:
1)onCreate
准备您的活动 - 因此,在此方法完成之前,您在此处所做的任何操作都不会显示!例如 - 您将永远无法在此处更改TextView
的文字超过一个时间,因为只会绘制最后一个更改,因此对用户可见!
2)请注意,Android程序默认只在 ONE 主题中运行!因此:永远不要在主线程中使用负责UI的Thread.sleep()
或Thread.wait()
! (请阅读"Keep your App Responsive"了解更多信息!)
您的活动初始化的作用是:
TextView
对象t
!TextView
中选择您的布局t
。t
的文字(但请记住:只有 onCreate()
完成后才会显示,并且应用程序的主要事件循环会运行!)< / LI>
onCreate
方法中等待 10秒 - 此绝不能完成,因为它会停止所有UI活动并且肯定会强制ANR(应用程序)没有回复,请参阅上面的链接!)onCreate()
方法完成并且其他几个Activity lifecycle方法已处理完毕,就会显示此文本!解决方案:
仅在onCreate()
中设置一次文字 - 这必须是应该可见的第一个文字。
创建Runnable
和Handler
private final Runnable mUpdateUITimerTask = new Runnable() {
public void run() {
// do whatever you want to change here, like:
t.setText("Second text to display!");
}
};
private final Handler mHandler = new Handler();
将此runnable作为处理程序安装,可以在onCreate()
中安装(但请阅读下面的建议):
// run the mUpdateUITimerTask's run() method in 10 seconds from now
mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);
建议:确保你知道Activity
的生命周期!如果您在onCreate()
中执行此类操作,则只有在Activity
创建第一次时才会发生这种情况! Android可能会让您的Activity
保持更长时间的活着,即使它不可见!
当用户再次“启动”它 - 它仍然存在 - 您将不再看到您的第一个文本了!
=&GT;始终在onResume()
中安装处理程序并在onPause()
中禁用它们!否则,当Activity
根本不可见时,您将获得“更新”!
在您的情况下,如果您想在重新激活时再次看到第一个文字,则必须在onResume()
中设置,而不是onCreate()
!
答案 1 :(得分:45)
我刚刚在android-discuss google group中发布了这个答案
如果您只是想在视图中添加文字,以便显示“第一步:爆蛋第二步:煎鸡蛋”然后考虑使用t.appendText("Step Two: fry egg");
代替t.setText("Step Two: fry egg");
如果你想完全改变TextView
中的内容,以便它在启动时说“第一步:爆蛋”然后它会说“第二步:煎鸡蛋”,你可以随时使用
Runnable example sadboy给了
祝你好运答案 2 :(得分:14)
新文本视图的第一行是不必要的
t=new TextView(this);
你可以这样做
TextView t = (TextView)findViewById(R.id.TextView01);
就这里睡觉的后台线程而言,这是一个例子,但我认为有一个更好的计时器。这里是一个使用计时器的好例子的链接 http://android-developers.blogspot.com/2007/11/stitch-in-time.html
Thread thr = new Thread(mTask);
thr.start();
}
Runnable mTask = new Runnable() {
public void run() {
// just sleep for 30 seconds.
try {
Thread.sleep(3000);
runOnUiThread(done);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Runnable done = new Runnable() {
public void run() {
// t.setText("done");
}
};
答案 3 :(得分:6)
@ user264892
我发现在使用String变量时,我需要使用字符串“”加前缀或显式转换为CharSequence。
所以而不是:
String Status = "Asking Server...";
txtStatus.setText(Status);
尝试:
String Status = "Asking Server...";
txtStatus.setText((CharSequence) Status);
或:
String Status = "Asking Server...";
txtStatus.setText("" + Status);
或者,因为你的字符串不是动态的,甚至更好:
txtStatus.setText("AskingServer...");
答案 4 :(得分:3)
根据您的建议,我使用句柄和runnables使用“计时器”切换/更改TextView的内容。出于某种原因,在运行时,应用程序总是会跳过第二步(“第二步:炒蛋”),只显示最后一步(第三步)(“第三步:送蛋”)。
TextView t;
private String sText;
private Handler mHandler = new Handler();
private Runnable mWaitRunnable = new Runnable() {
public void run() {
t.setText(sText);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMonster = BitmapFactory.decodeResource(getResources(),
R.drawable.monster1);
t=new TextView(this);
t=(TextView)findViewById(R.id.TextView01);
sText = "Step One: unpack egg";
t.setText(sText);
sText = "Step Two: fry egg";
mHandler.postDelayed(mWaitRunnable, 3000);
sText = "Step three: serve egg";
mHandler.postDelayed(mWaitRunnable, 4000);
...
}
答案 5 :(得分:0)
:)你以错误的方式使用线程。 只需执行以下操作:
private void runthread()
{
splashTread = new Thread() {
@Override
public void run() {
try {
synchronized(this){
//wait 5 sec
wait(_splashTime);
}
} catch(InterruptedException e) {}
finally {
//call the handler to set the text
}
}
};
splashTread.start();
}
就是这样。
答案 6 :(得分:0)
将文本设置为sam textview两次将覆盖第一个书面文本。 所以当我们第二次使用settext时,我们只需附加新的字符串,如
textview.append("Step Two: fry egg");
答案 7 :(得分:0)
@Zordid @Imbda答案很棒,但我发现如果我把
mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);
在run()方法和
中mHandler.postDelayed(mUpdateUITimerTask, 0);
在onCreate方法中使事物不断更新。