RATlius
@RATlius
Разработчик Android

Почему AsynkTask.onProgressUpdate() не разрешает менять текст TextView?

class AsyncProgressUpdate extends AsyncTask<Void, Integer, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loadingStatus.setText("Подготовка");
        }

        @Override
        protected Void doInBackground(Void... voids) {
            try {
                Thread.sleep(1_000);
                onProgressUpdate(1);
                for (int i=1; i<=4; i++) {
                    Thread.sleep(1_000);
                    onProgressUpdate(i*25);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            int currentProgress = values[0];
            String textLoading = "";
            switch (currentProgress) {
                case 1:
                    textLoading = "Подготовка";
                    break;
                case 25:
                    textLoading = "Инициализация";
                    break;
                case 50:
                    textLoading = "Проверка пароля";
                    break;
                case 75:
                    textLoading = "Подготовка";
                    break;
                case 100:
                    textLoading = "Завершение";
                    break;
            }
            progressBar.setProgress(currentProgress);
            loadingStatus.setText(textLoading); //тут ошибка
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            Toast.makeText(SplashActivity.this, "loading Finish", Toast.LENGTH_SHORT).show();
            loadingStatus.setText("Test Text");
        }
    }


Вызывается код стандартным образом
new AsyncProgressUpdate().

текст ошибки
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
                  Process: dev.jorik.lawlex, PID: 6238
                  java.lang.RuntimeException: An error occured while executing doInBackground()
                      at android.os.AsyncTask$3.done(AsyncTask.java:304)
                      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
                      at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                      at java.lang.Thread.run(Thread.java:818)
                   Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                      at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
                      at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:874)
                      at android.view.View.requestLayout(View.java:17476)
                      at android.view.View.requestLayout(View.java:17476)
                      at android.view.View.requestLayout(View.java:17476)
                      at android.view.View.requestLayout(View.java:17476)
                      at android.view.View.requestLayout(View.java:17476)
                      at android.view.View.requestLayout(View.java:17476)
                      at android.support.constraint.ConstraintLayout.requestLayout(ConstraintLayout.java:3172)
                      at android.view.View.requestLayout(View.java:17476)
                      at android.widget.TextView.checkForRelayout(TextView.java:6871)
                      at android.widget.TextView.setText(TextView.java:4057)
                      at android.widget.TextView.setText(TextView.java:3915)
                      at android.widget.TextView.setText(TextView.java:3890)
                      at dev.jorik.lawlex.SplashActivity$AsyncProgressUpdate.onProgressUpdate(SplashActivity.java:80)
                      at dev.jorik.lawlex.SplashActivity$AsyncProgressUpdate.doInBackground(SplashActivity.java:46)
                      at dev.jorik.lawlex.SplashActivity$AsyncProgressUpdate.doInBackground(SplashActivity.java:35)
                      at android.os.AsyncTask$2.call(AsyncTask.java:292)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                      at java.lang.Thread.run(Thread.java:818) 


Как сделать так, чтобы я могу изменить textView из стороннего потока AsyncTask?
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
RATlius
@RATlius Автор вопроса
Разработчик Android
Проблема решилась банально.
Вызов метода AsyncTask.onProgressUpdate() осуществляется через AsyncTask.publishProgress();
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@aol-nnov
вся информация в сообщении об ошибке:
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Ответ написан
@davidnum95
Если в лоб решать задачу, то написать хелпер для запуска кода на основном потоке:
public static void runOnMainThread(Runnable runnable) {
        new Handler(Looper.getMainLooper()).post(runnable);
    }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы