Android Установка флажка Метод setChecked () в AsyncTask выдает ошибку? - PullRequest
1 голос
/ 18 марта 2020

Я хочу сгенерировать свой пользовательский интерфейс в AsyncTask (потому что генерация занимает почти секунду). Я получил данные, а затем сгенерировал все элементы пользовательского интерфейса и макет в фоновом режиме, а в onPostExecute я добавил готовый макет пользовательского интерфейса в contentFrameLayout.

FrameLayout contentFrameLayout;  // this is a FrameLayout in the BaseActivity

private class loadUiAsync extends AsyncTask<List<MyData>, Void, LinearLayout>{
        LinearLayout mainLayout;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog();

            mainLayout =  ( LinearLayout ) LayoutInflater.from(MainActivity.this).inflate(R.layout.content_layout, null, false);
        }

        @Override
        protected LinearLayout doInBackground( List<MyData>... datas ) {

            // I create and generate a lot's of views from the datas, and add them to the mainLayout.
            checkBox.setChecked(/* TRUE or FALSE value based on data */);          // ----> THIS CAUSES THE CRASH

            return mainLayout;
        }

         @Override
        protected void onPostExecute( LinearLayout mainLayout ) {
            super.onPostExecute(mainLayout);

            contentFrameLayout.removeAllViews();
            contentFrameLayout.addView(mainLayout);

            dismissDialog();
        }
}

Это прекрасно работает на android 10, но вылетает на android 5 и 6:

03-18 10:01:11.443 11598-12560/com.my.app E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #4
    Process: com.my.app, PID: 11598
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:309)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
        at java.util.concurrent.FutureTask.run(FutureTask.java:242)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
     Caused by: android.util.AndroidRuntimeException: Animators may only be run on Looper threads
        at android.animation.ValueAnimator.start(ValueAnimator.java:1069)
        at android.animation.ValueAnimator.start(ValueAnimator.java:1117)
        at android.animation.ObjectAnimator.start(ObjectAnimator.java:852)
        at android.animation.AnimatorSet.start(AnimatorSet.java:586)
        at android.animation.AnimatorSet.start(AnimatorSet.java:586)
        at android.animation.AnimatorSet.start(AnimatorSet.java:586)
        at androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat.start(AnimatedVectorDrawableCompat.java:719)
        at androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat$AnimatedVectorDrawableTransition.start(AnimatedStateListDrawableCompat.java:439)
        at androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat.selectTransition(AnimatedStateListDrawableCompat.java:346)
        at androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat.onStateChange(AnimatedStateListDrawableCompat.java:280)
        at android.graphics.drawable.Drawable.setState(Drawable.java:680)
        at android.widget.CompoundButton.drawableStateChanged(CompoundButton.java:464)
        at androidx.appcompat.widget.AppCompatCheckBox.drawableStateChanged(AppCompatCheckBox.java:224)
        at android.view.View.refreshDrawableState(View.java:17061)
        at android.widget.CompoundButton.setChecked(CompoundButton.java:145)
        at com.my.app.view.ui.MainActivity$loadUiAsync.doInBackground(MainActivity.java:396)
        at com.my.app.view.ui.MainActivity$loadUiAsync.doInBackground(MainActivity.java:153)
        at android.os.AsyncTask$2.call(AsyncTask.java:295)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
        at java.lang.Thread.run(Thread.java:818) 

1 Ответ

0 голосов
/ 18 марта 2020
Caused by: android.util.AndroidRuntimeException: Animators may only be run on Looper threads

Вы можете попробовать с помощью runOnUiThread.

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

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                 checkBox.setChecked(true/false);
            }
});
...