E
E
Egor2018-10-30 11:02:59
Android
Egor, 2018-10-30 11:02:59

Why doesn't AsyncTask.onProgressUpdate() allow TextView text to be changed?

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

The code is called in the standard way
new AsyncProgressUpdate().
the error text
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) 

How can I make it so that I can change the textView from a third party AsyncTask thread?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
E
Egor, 2018-10-30
@RATlius

The problem was trivially solved.
The AsyncTask.onProgressUpdate() method is called via AsyncTask.publishProgress();

A
aol-nnov, 2018-10-30
@aol-nnov

all information in the error message:

Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

D
davidnum95, 2018-10-30
@davidnum95

If you solve the problem head-on, then write a helper to run the code on the main thread:

public static void runOnMainThread(Runnable runnable) {
        new Handler(Looper.getMainLooper()).post(runnable);
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question