обновить основной поток пользовательского интерфейса из подсети AsyncTask - PullRequest
0 голосов
/ 17 февраля 2012

Я новичок в Android и у меня много проблем, чтобы получить простое обновление для графического интерфейса.

из моего основного класса я называю AsyncTask:

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

Асинхронный класс выглядит следующим образом

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


}

При попытке обновить 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)

Что я могу сделать, чтобы избежать этого?

к сожалению

onProgressUpdate

никогда не достигается.

спасибо

Ответы [ 3 ]

1 голос
/ 17 февраля 2012

Решение было правильно переопределить onProgressUpdate:

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

В любом случае, спасибо.

1 голос
/ 17 февраля 2012

Ваша проблема связана с вашим закомментированным кодом.Вы не можете обновить представление за пределами основного потока.Вы лишаете законной силы текстовое представление в Задании (которое запускается в своем собственном представлении).Чтобы остановить проблему, вам нужно обновить текстовое представление в onProgressUpdate, а не в soInBackground.

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

В AsyncTask есть 4 части.Вы можете обновить вид из любой части, кроме формы doInBackground.Удалите publishProgress(labelText); оттуда, и вы достигнете onProgressUpdate.

Посмотрите здесь http://developer.android.com/reference/android/os/AsyncTask.html

...