В моем приложении мне нужно загрузить кучу файлов. В моем первоначальном плане использовался отдельный AsyncTask для каждого файла, поэтому я могу уведомить остальную часть приложения, когда загружается каждый файл. Я обнаружил, что он тестирует, что, хотя это работает, кажется, что он действительно неэффективен в работе. Есть ли хороший способ использовать одну AsyncTask или, возможно, службу для загрузки файлов и уведомления о каждом файле?
Нет причин использовать многочисленные AsyncTask
s, так как вы можете создать список имен файлов, передать его в одиночную AsyncTask
и после загрузки каждого файла опубликовать процесс загрузки с помощью publishProgress()
и onProgressUpdate()
, который запускается в UI и может легко уведомлять о других действиях в вашем приложении.
private class DownloadFilesTask extends AsyncTask<URL, String, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
for (int i = 0; i < count; i++) {
Downloader.downloadFile(urls[i]);
publishProgress(urls[i].toString());
}
return 0;
}
protected void onProgressUpdate(String... progress) {
// notify whomever you like with url from progress[0]
// this is run on UI thread
}
protected void onPostExecute(Long result) {
// do something else
// this is also run on UI thread
}
}
С точки зрения памяти и сети вам будет лучше использовать только один AsyncTask (или поток Java) и загружать все файлы по одному. Это значительно улучшает чувствительность устройства и также потребляет немного памяти. В случае, если вы можете контролировать серверную сторону, я также предлагаю вам заархивировать файлы меньшего размера в один архив (мой проект также загружает большое количество файлов через HTTP), и он показывает значительное улучшение скорости, если файлы объединены в архивы размером около 2- 4 МБ и загружен. Если вы загружаете, используя только TCP/IP-соединение, неважно, насколько велики файлы, если вы не будете повторно устанавливать соединение каждый раз. Но снова для HTTP самый большой размыв времени обычно является установлением соединения.
Удаленная служба будет работать, но я думаю, что это неправильный подход, так как у вас есть только ограниченная функциональность.
Я бы использовал AsyncTask, но вызвал его методом.
Когда вы закончите в AsyncTask, снова вызовите метод, который будет создавать новую AsyncTask после удаления элемента в списке или обновления некоторого счетчика.
Помните, что AsyncTask нельзя использовать повторно, поэтому его нужно создавать каждый раз.
AsyncTask
другойAsyncTask
когда все будет готово, загрузив следующий файл в ваш большой список.