Наличие ссылки на объект внутри asynctasks не позволяет ему обновлять пользовательский интерфейс

public class Container {

    public process(T result){
       // Update UI
    }

    public anotherMethodThatUpdatesUI(T result){
       // Update UI
    }
    public SomeTask extends AsyncTask<T,T,T> {
        private Container container;
        public someTask(Container container){
            this.container = container; 
        }

        protected void onPostExecute(T result) {
            super.onPostExecute(result);
            container.process(result);

        }
    }
}

Сначала я вызываю метод AsyncTaskexecute, который работает правильно. Но после этого вызов anotherMethodThatUpdatesUI завершается ошибкой с этим исключением:

Can't create handler inside thread that has not called Looper.prepare()

Но если я удалю ссылку на Container внутри AsyncTask и вызову process напрямую. Я не получаю сообщения об ошибке.

public SomeTask extends AsyncTask<T,T,T> {
    private Container container;
    public someTask(Container container){
        // this.container = container; 
    }

    protected void onPostExecute(T result) {
        super.onPostExecute(result);
        process(result);
    }
}

Как вы обновляете пользовательский интерфейс внутри этих методов?

Jimmy 17.04.2018 16:45

У меня есть ссылка на экземпляр фрагмента, и я вызываю некоторые общедоступные методы для этого фрагмента.

LonsomeHell 18.04.2018 09:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
36
1

Ответы 1

Вероятно, вы вызываете fomr anotherMethod внутри doInBackground, поскольку в этом другом потоке вам нужно опубликовать сообщение в исходном, вы можете сделать это с помощью publishProgress изнутри doInBackground и обработать метод onProgressUpdated из AsyncTask.

public SomeTask extends AsyncTask<T,T,T> {
    private Container container;
    public someTask(Container container){
        this.container = container; 
    }
    public void doInBackground(T ... args) { 
         publishProgress(step1);
         publishProgress(step2);
         publishProgress(step3);
    }
    void onProgressUpdate(T step){
         anotherMethodThatUpdatesUI(step);
    }
}

Задача async завершается правильно и обновляет пользовательский интерфейс без каких-либо проблем. Проблема возникает после этого. Странная вещь, проблема возникает только в том случае, если AsyncTask сохраняет ссылку на родительский объект, если он не хранит ссылку на объект, код работает нормально.

LonsomeHell 18.04.2018 09:08

@LonsomeHell, вы создаете новый вид внутри doInBackground?

Marcos Vasconcelos 18.04.2018 15:16

Мне удалось обойти проблему, я отредактирую вопрос завтра. Я ищу не исправление, а причину, по которой сохранение метода экземпляра внутри asyncTask создает проблему. Но когда к одному и тому же методу в том же объекте обращаются без сохранения ссылки внутри. Решение перестает работать.

LonsomeHell 18.04.2018 16:16

Я не создаю экземпляр View внутри doInBackground. Я обращаюсь к внутреннему веб-серверу для получения данных.

LonsomeHell 18.04.2018 16:17

Это никогда не должно быть проблемой, единственная проблема - это доступ к представлениям из разных потоков, чем тот, который их создает. Если вы добавите достаточно кода, чтобы воспроизвести проблему, мы сможем сказать, что это такое.

Marcos Vasconcelos 18.04.2018 16:25

Другие вопросы по теме