我试图做其他事情,但继续删除代码,认为简化事情将有助于识别我的错误。这就是我剩下的(经过大量的简化),但我仍然没有得到它为什么它不应该这样做!
public class MyOwnTimerActivity extends Activity {
int timeLeft = 5;
TextView timerTextView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button timerButton = (Button) findViewById(R.id.button1);
timerTextView = (TextView) findViewById(R.id.timerText);
Thread timer = new Thread() {
public void run() {
try {
sleep(3000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally{
timerTextView.setText("something");
}
}
};
timer.start();
}
}
错误:应用程序在3秒后崩溃,即在计时器熄灭后崩溃。
答案 0 :(得分:4)
啊,是))这是因为您尝试从非UI线程修改UI
有几种方法可以从另一个线程修改UI:
Handler
类覆盖handleMessage()
方法
Activity
类调用runOnUI()
方法,传递Runnable
对象,其中run()
方法修改了UI
View.post()
或View.postDelayed()
方法
在您的情况下,最后一个变体是最方便的。以这种方式修改您的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button timerButton = (Button) findViewById(R.id.button1);
timerTextView = (TextView) findViewById(R.id.timerText);
timerTextView.postDelayed(
new Runnable() {
@Override
run() {
timerTextView.setText("something");
}
}, 3000);
}
答案 1 :(得分:2)
您不应该从工作线程更改UI。使用在主线程上初始化的Handler和一个ad-hoc Runnable来在主线程上执行setText()。
Handler h = new Handler();
Thread timer = new Thread() {
//...
finally
{
h.post(new Runnable(){
public void run()
{
timerTextView.setText("something");
}
});
}
实际上,可以使用Handler.postDelayed()重写整个代码段。但是你最终可能想用一个线程来做更多有趣的事情。
答案 2 :(得分:0)
您是否尝试过使用runOnUI从UI线程设置Text?你可以这样做:
runOnUiThread(new Runnable() {
public void run()
{
timerTextView.setText("something");
}
});
请记住,您对timerTextView的引用以及您想要显示的任何文本都必须修改为最终变量,以便从另一个线程引用它。