Android:由于CalledFromWrongThreadException,秒表应用程序崩溃

时间:2012-02-10 15:04:41

标签: android stopwatch thread-sleep

这是我在Android上使用秒表应用程序的代码:

package com.google.labyrinth;

public class Tabalicious extends Activity implements OnClickListener, Runnable
{
    TextView    stopwatchCounter;

    long        startTime, stopTime;

    Thread      stopwatch;
    Button      buttonStart;
    Button      buttonStop;

    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView( R.layout.tabalicious );


        stopwatchCounter    = (TextView) findViewById ( R.id.txtStopwatchCounter );
        buttonStart         = ( Button ) findViewById ( R.id.buttonStart );
        buttonStop          = ( Button ) findViewById ( R.id.buttonStop );

        buttonStart.setOnClickListener( this );

        buttonStop.setOnClickListener( this );
        buttonStop.setEnabled(false);

    }

    public void onClick(View viewClicked)
    {

        switch( viewClicked.getId() )
        {
        case R.id.buttonStart:

            this.buttonStart.setEnabled(false);
            this.buttonStop.setEnabled(true);

            this.startTime = System.currentTimeMillis();

            stopwatch = new Thread(this);
            stopwatch.start();

            break;

        case R.id.buttonStop:

                this.buttonStop.setEnabled(false);
                this.buttonStart.setEnabled(true);

            try {
                stopwatch.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            break;


        }

    }

    public void run()
    {
                    //Update after 5 seconds.
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }

            this.stopTime = System.currentTimeMillis();
            this.stopwatchCounter.setText( String.valueOf( (this.stopTime - this.startTime) ) ); //<- Debugger Info: This line is at the top of the call stack.
    }

}

问题是,当我运行应用程序时,我得到一个CalledFromWrongThread异常:

  

02-10 19:53:32.835:E / AndroidRuntime(18482):致命异常:   Thread-10 02-10 19:53:32.835:E / AndroidRuntime(18482):

     

android.view.ViewRoot $ CalledFromWrongThreadException:只有   创建视图层次结构的原始线程可以触及其视图。   02-10 19:53:32.835:E / AndroidRuntime(18482):

     

在android.view.ViewRoot.checkThread(ViewRoot.java:3092)02-10   19:53:32.835:E / AndroidRuntime(18482):

     

在android.view.ViewRoot.invalidateChild(ViewRoot.java:677)02-10   19:53:32.835:E / AndroidRuntime(18482):

     

在android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:703)   02-10 19:53:32.835:E / AndroidRuntime(18482):

     

在android.view.ViewGroup.invalidateChild(ViewGroup.java:2597)02-10   19:53:32.835:E / AndroidRuntime(18482):

     

在android.view.View.invalidate(View.java:5326)02-10 19:53:32.835:   E / AndroidRuntime(18482):

     

在android.widget.TextView.checkForRelayout(TextView.java:5761)02-10   19:53:32.835:E / AndroidRuntime(18482):

     

在android.widget.TextView.setText(TextView.java:2814)02-10   19:53:32.835:E / AndroidRuntime(18482):

     

在android.widget.TextView.setText(TextView.java:2682)02-10   19:53:32.835:E / AndroidRuntime(18482):

     

在android.widget.TextView.setText(TextView.java:2657)02-10   19:53:32.835:E / AndroidRuntime(18482):at   com.google.labyrinth.Tabalicious.run(Tabalicious.java:144)02-10   19:53:32.835:E / AndroidRuntime(18482):at   java.lang.Thread.run(Thread.java:1027)

我不太清楚发生了什么。我很感激你的帮助。谢谢!

2 个答案:

答案 0 :(得分:2)

您正在尝试编辑UI元素,但您不在UI线程上。在Android中,UI元素只能由UI线程编辑。在另一个线程上进行计算后,有很多方法可以更新UI元素,包括调用runOnUiThread()方法,使用Handler或覆盖AsyncTask的PostExecute()方法。

答案 1 :(得分:0)

这只是因为你这样做:

this.stopwatchCounter.setText(String.valueOf((this.stopTime - this.startTime)));

在秒表线程内,你不能触摸视图,因为它不是UIThread。