AsyncTask позволяет запускать задачу в фоновом потоке при публикации результатов в потоке пользовательского интерфейса.
Пользователь всегда должен взаимодействовать с приложением, поэтому важно не блокировать основной поток (UI) такими задачами, как загрузка содержимого из Интернета.
Вот почему мы используем
AsyncTask
.Он предлагает простой интерфейс , обертывающий очередь сообщений и обработчик потока пользовательского интерфейса, которые позволяют отправлять и обрабатывать запущенные объекты и сообщения из других потоков .
blockquote>Реализация
AsyncTask - это общий класс. (Он принимает параметризованные типы в своем конструкторе.)
Он использует эти три общих типа:
Params
- тип параметров, отправленных в задачу после выполнения.
Progress
- тип единиц прогресса, опубликованных во время фонового вычисления.
Result
- тип результата фонового вычисления.] Не все типы всегда используются асинхронной задачей. Чтобы пометить тип как неиспользованный, просто используйте тип Void:
blockquote>
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Эти три параметра соответствуют трем основным функциям, которые вы можете переопределить в
AsyncTask
:
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Для выполнения AsyncTask
вызывать
execute()
с параметрами, которые будут отправлены в фоновое задание.Что происходит
- В главном / пользовательском потоке вызывается
onPreExecute()
. (Чтобы инициализировать что-то в этом потоке, например, показать индикатор выполнения в пользовательском интерфейсе.)- В фоновом потоке вызывается
doInBackground(Params...)
. (Параметры - это те, которые передаются функции Execute.) В тех случаях, когда должно выполняться многолетняя задача. Чтобы использовать AsyncTask, необходимо переопределить хотя быdoInBackground()
. ВызовитеpublishProgress(Progress...)
, чтобы обновить отображение прогресса в пользовательском интерфейсе, пока выполняется фоновое вычисление. (например, анимировать индикатор выполнения или показывать журналы в текстовом поле.) Это вызывает вызовonProgressUpdate()
.- В фоновом потоке результат возвращается из
doInBackground()
. Это приводит к следующему шагу.- В главном / пользовательском потоке,
onPostExecute()
вызывается с возвращенным результатом.Примеры
Используя снова Например, задача блокировки заключается в загрузке чего-либо из Интернета,
- Пример A загружает изображение и отображает его в ImageView,
- , в то время как в примере B загружаются некоторые файлы.
Пример A
Метод
doInBackground()
загружает изображение и сохраняет его в объекте типа BitMap. МетодonPostExecute()
принимает растровое изображение и помещает его в ImageView.class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ImageView bitImage; public DownloadImageTask(ImageView bitImage) { this.bitImage = bitImage; } protected Bitmap doInBackground(String... urls) { String urldisplay = urls[0]; Bitmap mBmp = null; try { InputStream in = new java.net.URL(urldisplay).openStream(); mBmp = BitmapFactory.decodeStream(in); } catch (Exception e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return mBmp; } protected void onPostExecute(Bitmap result) { bitImage.setImageBitmap(result); } }
Пример B
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); publishProgress((int) ((i / (float) count) * 100)); // Escape early if cancel() is called if (isCancelled()) break; } return totalSize; } protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } protected void onPostExecute(Long result) { showDialog("Downloaded " + result + " bytes"); } }
Пример выполнения B
new DownloadFilesTask().execute(url1, url2, url3);