Результат AsyncTask отличается от обычной функции

#android #android-asynctask

#Android #android-асинхронная задача #android-asynctask

Вопрос:

У меня есть представление, которое принимает жесты свайпа. это должно вызвать создание и setContentView (layout) для основного действия. (Представление находится в макете Основного действия)

Когда я пытаюсь сделать это в рамках asynctask, он оставляет все изображения для макета? как будто это еще не закончилось . Возможно , есть что — то , чего я не до конца понимаю .

это частичный код из view.java

 Main.mHandler.post(new Runnable()
                    { 
                        public void run()
                        {
                            new Main.GetNavigationLayout().execute(url);
                    }
                    });
  

URL-адрес — это расположение XML-файла, который я использую для создания нового макета.

GetNavigationLayout — это асинхронная задача

код, который является AsyncTask в Main.java :

 public static class GetNavigationLayout extends AsyncTask<String, Void, CustomLayout> {
    boolean isDone = false; 
     @Override
        protected EvadoLayout doInBackground(String... url)
        {
            CustomLayout layout = new CustomLayout(Main);
                Looper.prepare();       
                try 
                {

                    String newpage = url[0];
                    Document doc = XmlImporter.GetNewPlayer(newpage);

                    if (doc == null)
                    {
                        layout = null; 
                    }       

                    layout.LoadXml(doc);  // cause drawing of objects etc. 



                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }

                isDone = true;
                //Looper.loop();   // causes it to never return...
            return layout;

        }

        @Override
        protected void onPostExecute(CustomLayout layout)
        {
            if (isDone)
              Main.setContentView(layout);
        }
 }
  

теперь это показывает все, кроме изображений, тогда как, если я запускаю это без AsyncTask, он отображает все в макете.
что я упускаю из виду?

Ответ №1:

   layout.LoadXml(doc);  // cause drawing of objects etc. 
  

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

Комментарии:

1. Это работает. Спасибо. Плохо, что это работает так, хотя я искал способ рисовать несколько макетов одновременно. (следовательно, асинхронный). Я думаю, мне понадобится еще несколько тестов. Спасибо! затем добавьте их в SwipeView.

2. после некоторого тестирования похоже, что я столкнулся с новой проблемой; 10-05 16:32:28.730: ОШИБКА / AndroidRuntime (2024): Вызвано: java.lang.RuntimeException: для каждого потока может быть создан только один цикл. насколько я могу судить, я не объявляю больше петлителей? если я удалю Looper.prepare(); AsyncTask завершится сбоем…

Ответ №2:

Вы можете опубликовать в пользовательском интерфейсе в onProgressUpdate (). Использование этого метода позволит вам оставаться внутри doInBackground и публиковать обновления в пользовательском интерфейсе, когда вы получите макет и продолжите работу внутри doInBackground. Используйте publishProgress() для отправки информации из doInBackground в поток пользовательского интерфейса.

Комментарии:

1. спасибо, чувак! Я попробую это, как только устраню эту ошибку цикла. «Для каждого потока может быть создан только один цикл» :

2. Вы можете удалить часть петлителя, она не нужна. Методы looper необходимы только в том случае, если вы пытаетесь внести изменения в пользовательский интерфейс из другого потока. Вы можете удалить части петлителя, если собираетесь вносить изменения в пользовательский интерфейс в onProgressUpdate.

3. Хорошо, итак, я попытался сделать то, что вы сказали, отправив сообщение в пользовательский интерфейс в onProgressUpdate(). Это работает нормально! Однако, похоже, я не могу избавиться от зацикливателя. Ошибка «Не удается создать обработчик внутри потока, который не вызывал Looper.prepare() «. также, когда я проверяю отладчик, я вижу, что моя AsyncTask не уничтожается после использования? Есть ли у меня способ потерять поток после его завершения?

4. не обращайте внимания на эту часть обработчика! исправлено … все еще делал некоторые публикации в пользовательском интерфейсе 🙂