-2

我有一个 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()); 它工作正常。谁能给我解决方案。我是安卓新手。

4

5 回答 5

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();
       }

     }
于 2013-05-30T06:35:58.663 回答
2

当我删除 tvTimer.setText((String.valueOf(time)).toString()); 它工作正常

因为您正在尝试从非 ui 线程更改 TextView 文本,所以请使用runOnUiThreadHandler从其他线程更新 TextView

于 2013-05-30T06:31:24.313 回答
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()。而不是在等待工作线程完成时阻塞,您的主线程应该为其他线程提供一个处理程序,以便在完成后回发。以这种方式设计您的应用程序将使您的应用程序的 UI 线程保持对输入的响应,从而避免由 5 秒输入事件超时引起的 ANR 对话框。

要停止使用此 m_handler.removeCallbacks(m_handlerTask);

于 2013-05-30T06:31:33.417 回答
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--;
        }
    });
}
于 2013-05-30T06:33:40.717 回答
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();
        }

     }
于 2013-05-30T06:31:46.570 回答