#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. не обращайте внимания на эту часть обработчика! исправлено … все еще делал некоторые публикации в пользовательском интерфейсе 🙂