Фон / Теория
AsyncTask позволяет запускать задачу в фоновом потоке при публикации результатов в потоке пользовательского интерфейса.
Пользователь долженвсегда в состоянии взаимодействовать с приложением, поэтому важно , чтобы не блокировать основной поток (UI) такими задачами, как загрузка контента из Интернета.
Этопочему мы используем AsyncTask
.
. Он предлагает простой интерфейс , заключающий в себе очередь сообщений потока обработчика и обработчик, который позволяет отправлять и обрабатывать выполняемые объекты и сообщения из другихthreads .
Реализация
AsyncTask - универсальный класс.(Он принимает параметризованных типов в своем конструкторе.)
Использует эти три универсальных типа:
Params
- тип параметров, отправляемых заданию при выполнении.
Progress
- тип единиц прогресса, публикуемых при фоновом вычислении.
Result
- тип результата фонового вычисления.
Не все типы всегда используются асинхронной задачей.Чтобы пометить тип как неиспользуемый, просто используйте тип Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Эти три параметра соответствуют трем основным функциям , которые можно переопределить в AsyncTask
:
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Для выполнения AsyncTask
- Вызов
execute()
с параметрами, которые необходимо отправить в фоновую задачу.
Что происходит
На вызывается основной / пользовательский интерфейс , onPreExecute()
.
- Для инициализациичто-то в этой теме.(Например, в пользовательском интерфейсе отображается индикатор выполнения.)
В фоновом потоке , doInBackground(Params...)
вызывается.
- (
Params
были переданы через execute
.) - Где должна выполняться длительная задача.
Должен переопределить хотя бы doInBackground()
для использования AsyncTask.
Вызов publishProgress(Progress...)
для обновления пользовательского интерфейса с отображением прогресса (например, анимация пользовательского интерфейса или напечатанный текст журнала) в то время как фонвычисления все еще выполняются.
- Вызывает
onProgressUpdate()
.
Вкл фоновый поток результат возвращается из doInBackground()
.
- (Это вызывает следующий шаг.)
В main / UI thread , 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);