Android: приложение секундомера падает из-за CalledFromWrongThreadException - PullRequest
0 голосов
/ 10 февраля 2012

Вот мой код для приложения секундомера на 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):

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

at 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):

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

Мне не совсем понятно, что происходит. Буду признателен за вашу помощь. спасибо!

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

Вы пытаетесь редактировать элементы пользовательского интерфейса, но вы не в потоке пользовательского интерфейса. В Android элементы пользовательского интерфейса могут редактироваться только потоком пользовательского интерфейса. Есть много способов обновить элементы пользовательского интерфейса после выполнения вычислений в другом потоке, включая вызов метода runOnUiThread (), использование обработчика или переопределение метода PostExecute () AsyncTask.

0 голосов
/ 10 февраля 2012

это только потому, что вы делаете:

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

внутри потока секундомера, вы можетене трогайте вид, потому что это не UIThread.

...