Android中的线程--->不幸的是,ThreadApp已经停止了

时间:2013-05-30 06:29:06

标签: android

我有一个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的新手。

5 个答案:

答案 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文本,因此请使用runOnUiThreadHandler从其他线程更新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();
        }

     }