我有一个textview,我可以用来显示倒数计时器。我想使用带有Runnable接口的Thread类。
我为此编写了以下代码,但它给出了运行时错误不幸的是ThreadApp已停止
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity implements Runnable
{
TextView tvTimer;
Thread timerThread;
int time=30;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTimer =(TextView)findViewById(R.id.textView1);
timerThread= new Thread(this);
timerThread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void run()
{
try
{
Thread.sleep(1000);
tvTimer.setText((String.valueOf(time)).toString());
time--;
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
同时当我删除 tvTimer.setText((String.valueOf(time))。toString()); 时,它工作正常。谁能为我提供解决方案。我是android的新手。
答案 0 :(得分:5)
您可以像使用RunOnUiThread一样使用更新UI
@Override
public void run()
{
try
{
Thread.sleep(1000);
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText((String.valueOf(time)).toString());
}
});
time--;
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
答案 1 :(得分:2)
当我删除tvTimer.setText((String.valueOf(time))。toString());它 工作正常
因为您正在尝试从非ui线程更改TextView文本,因此请使用runOnUiThread或Handler从其他线程更新TextView
答案 2 :(得分:1)
您正在尝试在计时器任务中更新ui。计时器任务在不同的线程上运行。在ui线程上更新ui。使用处理程序或runonuithread
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
@Override
public void run() {
tvTimer.setText((String.valueOf(time)).toString());
timer--;
// do something
m_handler.postDelayed(m_handlerTask, 1000); // instad of 1000 mention the delay in milliseconds
}
};
m_handlerTask.run();
或使用
@Override
public void run()
{
try
{
Thread.sleep(1000);
// should not call thread.sleep() bad design
// check the edit below
runOnUiThread(new Runnable(){
@Override
public void run(){
//update ui here
tvTimer.setText((String.valueOf(time)).toString());
}
});
time--;
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
编辑:在线程中使用Thread.sleep()是一个糟糕的设计。
http://developer.android.com/training/articles/perf-anr.html
从文档中引用。
如果您实现Thread或HandlerThread,请确保您的UI线程在等待工作线程完成时不会阻塞 - 不要调用Thread.wait()或Thread.sleep()。在等待工作线程完成时,主线程应该为其他线程提供一个Handler,以便在完成时回发。以这种方式设计应用程序将允许应用程序的UI线程保持对输入的响应,从而避免由5秒输入事件超时引起的ANR对话框。
停止使用此m_handler.removeCallbacks(m_handlerTask);
答案 3 :(得分:1)
new Thread(new Runnable() {
@Override
public void run() {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText((String.valueOf(time)).toString());
time--;
}
});
}
答案 4 :(得分:0)
您正在尝试更新UI元素,即线程中的TextView。你不能在一个线程中这样做。而是使用处理程序将更改发布到UI元素,如下所示 -
Handler handler = new Handler();
@Override
public void run()
{
try
{
Thread.sleep(1000);
handler.post(new Runnable()
{
public void run()
{
tvTimer.setText((String.valueOf(time)).toString());
}
time--;
});
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}