elCapitano
elCapitano

Reputation: 1841

update UI Main-thread from sub-thread AsyncTask

i am a newbie to android and have lots of trouble to get a simple update for a gui working.

from my main class i call a AsyncTask:

RepeatTimerTask task = new RepeatTimerTask(text, timerDummy);
task.execute(null);

The async class is like follows

class RepeatTimerTask extends AsyncTask<Void, String, Void> {
private long startTime;
private TextView txtToUpdate;
private Handler mHandler = new Handler();
long mStartTime = 0;
RepeatTimer timer;
long timerLength = 0;

public RepeatTimerTask(TextView txtToUpdate, RepeatTimer timer) {
    this.txtToUpdate = txtToUpdate;
    this.timer = timer;
    startTime = new Date().getTime();
    this.timerLength = timer.getTime() * 1000;
}




protected void onProgressUpdate(String newText) {
    try
    {

      txtToUpdate.setText(newText);
      txtToUpdate.invalidate();
    }catch (Exception e) {
        HErrorHandler.log(e);
    }
}

protected void onPostExecute() {
    txtToUpdate.setText("ALAAAAAMMMM");
}

@Override
protected Void doInBackground(Void... params) { 

    while (true) {
        try {
            synchronized (this) {
                this.wait(100);
            }
        } catch (InterruptedException e) {
            HErrorHandler.log(e);
            break;
        }

        long millis = System.currentTimeMillis() - startTime;
        if (millis <= 0
                || System.currentTimeMillis() > timerLength + startTime) {
            break;
        }
        int seconds = (int) (millis / 1000);
        int minutes = seconds / 60;
        seconds = seconds % 60;

        // !!!!!!!!!!!!!!!!!!   HERE THE ERROR1 OCCOURS!!!!!!!
        //txtToUpdate.setText(String.format("%d:%02d", minutes, seconds));
        //txtToUpdate.invalidate();
        String labelText = String.format("%d:%02d", minutes, seconds);
        publishProgress(labelText);
    }
    return null;
}


}

I get an error when i try to update the TextView:

    02-08 06:19:01.857: W/System.err(5625): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    02-08 06:19:01.887: W/System.err(5625):     at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
    02-08 06:19:01.897: W/System.err(5625):     at android.view.ViewRoot.requestLayout(ViewRoot.java:629)
    02-08 06:19:01.917: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:01.927: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:01.947: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:01.957: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:01.977: W/System.err(5625):     at android.widget.AbsListView.requestLayout(AbsListView.java:1102)
    02-08 06:19:01.997: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:02.007: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:02.030: W/System.err(5625):     at android.widget.TableLayout.requestLayout(TableLayout.java:226)
    02-08 06:19:02.037: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:02.057: W/System.err(5625):     at android.view.View.requestLayout(View.java:8267)
    02-08 06:19:02.068: W/System.err(5625):     at android.widget.TextView.checkForRelayout(TextView.java:5521)
    02-08 06:19:02.087: W/System.err(5625):     at android.widget.TextView.setText(TextView.java:2724)
    02-08 06:19:02.097: W/System.err(5625):     at android.widget.TextView.setText(TextView.java:2592)
    02-08 06:19:02.107: W/System.err(5625):     at android.widget.TextView.setText(TextView.java:2567)
    02-08 06:19:02.127: W/System.err(5625):     at com.hdit.RepeatTimerTask.doInBackground(RepeatTimerTask.java:74)
    02-08 06:19:02.147: W/System.err(5625):     at com.hdit.RepeatTimerTask.doInBackground(RepeatTimerTask.java:1)
    02-08 06:19:02.159: W/System.err(5625):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
    02-08 06:19:02.177: W/System.err(5625):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
    02-08 06:19:02.187: W/System.err(5625):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    02-08 06:19:02.207: W/System.err(5625):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
    02-08 06:19:02.217: W/System.err(5625):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
    02-08 06:19:02.237: W/System.err(5625):     at java.lang.Thread.run(Thread.java:1019)

What can i do to avoid this?

unfortunately the

onProgressUpdate

is never reached.

thank you

Upvotes: 0

Views: 2831

Answers (3)

user1204391
user1204391

Reputation: 92

There are 4 parts in an AsyncTask. You can update a view from any part except form doInBackground. Remove publishProgress(labelText); from there and you will reach onProgressUpdate.

Have a look here http://developer.android.com/reference/android/os/AsyncTask.html

Upvotes: 0

elCapitano
elCapitano

Reputation: 1841

The solution was to overrride the onProgressUpdate correctly:

@Override
protected void onProgressUpdate(String... values)

Thanks anyway.

Upvotes: 1

ahodder
ahodder

Reputation: 11439

Your issue comes from your commented out code. You cannot update a view outside of the main thread. You are invalidating the textview in the Task (which runs in its own view). To stop the issue, you will need to refresh the textview in onProgressUpdate - not in soInBackground.

Upvotes: 1

Related Questions