Этот код компилируется и запускается без NetworkOnMainThreadException
?
Ваша проблема - использование get()
В этой части:
Bitmap myimage;
try {
myimage = task.execute("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg").get();
downloadedImg.setImageBitmap(myimage);
}
вы пытаетесь получить изображение от task.execute(...)
, но task.get()
согласно документу:
[...]Waits if necessary for the computation to complete, and then retrieves its result.[...]
Итак, вы ждете, пока ваша «задача» будет выполнена в главном потоке, и заблокируете ее, пока не закончите. Из-за этого, ваш прогресс
никогда не виден, потому что UI-поток заблокирован. И как только твоя задача закончится,
прогресс настроен обратно, чтобы быть невидимым.
Более того, не изобретай велосипед. Используйте одну из доступных библиотек
для загрузки и кэширования изображений.
Например: Пикассо , Скольжение
Оба также предоставляют функциональность для использования (1) запасного варианта и (2) загрузки изображения.
Если вы все еще хотите попробовать это самостоятельно, не используйте Pokémon - "должен поймать всех" способ перехвата ваших исключений, но вместо этого обрабатывайте определенные Exceptions
, которые могут появляться и отображать сообщение для пользователя, отправлять его на трекер и т. д. Поймать только те исключения, которые вы ожидаете получить, в противном случае ... дать сбой.
Я не понимаю, почему вы должны ловить исключение там.
AsyncTask, Действия и утечки памяти
Далее, AsyncTasks
не аккуратно связаны с Activities
.
жизненный цикл. Когда вы запускаете свою задачу, и она выполняется в фоновом режиме, но
ваша деятельность заканчивается, эта задача будет по-прежнему жива и будет содержать ссылку на вашу деятельность. Это приводит к утечке памяти, потому что ГХ не может правильно выполнять свою работу, чтобы очистить после вас.
Сделайте свою AsyncTask как минимум статическим классом и остановите / убейте задачу, как только ваша деятельность закончится.
Несколько задач
Далее, проверьте, загрузили ли вы уже изображение, как только пользователь нажал кнопку или вы собираетесь создать несколько задач.
Итак, сделайте ваш ImageDownloader участником вашей деятельности и проверьте, выполняется ли он уже или уже выполнен. (Выньте это из вашего метода и поместите ниже заголовка класса активности). Когда ваша активность вызывает onPause()
или onDestroy()
, убейте задачу огнем.
Имейте в виду изменения ориентации тоже.
API задач Android вместо AsyncTask
Я настоятельно рекомендую использовать Android Task API. (com.google.android.gms.tasks
)
Он очень хорошо работает для задач, выполняемых как на основных, так и на рабочих нитях. Включает продолжения, обеспечивает Future
функциональность и может быть связан с деятельностью.
Ссылки: gms Task API Doc